#if defined(TSINGMA) || defined(TSINGMA_MX) || defined(TSINGMA_GX) || defined(ARCTIC)
/****************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "sal.h"
#include "ctc_error.h"
#include "ctc_macro.h"
#include "ctc_register.h"
#include "sys_usw_parser.h"
#include "sys_usw_common.h"
#include "sys_usw_lb_hash.h"
#include "drv_api.h"

#define SYS_LB_HASH_MPLS_SET_INNER_MAC(value, hash_ctl)       \
do                                                            \
{                                                             \
    if (CTC_FLAG_ISSET(value,CTC_LB_HASH_FIELD_MACDA_LO) &&   \
        CTC_FLAG_ISSET(value,CTC_LB_HASH_FIELD_MACDA_MI) &&   \
        CTC_FLAG_ISSET(value,CTC_LB_HASH_FIELD_MACDA_HI))     \
    {                                                         \
        SetParserMplsCtl(V,mplsMacDaHashEn_f,&hash_ctl,1);    \
    }                                                         \
    else                                                      \
    {                                                         \
        SetParserMplsCtl(V,mplsMacDaHashEn_f,&hash_ctl,0);    \
    }                                                         \
    if (CTC_FLAG_ISSET(value,CTC_LB_HASH_FIELD_MACSA_LO) &&   \
        CTC_FLAG_ISSET(value,CTC_LB_HASH_FIELD_MACSA_MI) &&   \
        CTC_FLAG_ISSET(value,CTC_LB_HASH_FIELD_MACSA_HI))     \
    {                                                         \
        SetParserMplsCtl(V,mplsMacSaHashEn_f,&hash_ctl,1);    \
    }                                                         \
    else                                                      \
    {                                                         \
        SetParserMplsCtl(V,mplsMacSaHashEn_f,&hash_ctl,0);    \
    }                                                         \
}while(0)

#define SYS_LB_HASH_MPLS_GET_INNER_MAC(flag,value,hash_ctl) \
do\
{\
    uint32 lable_en=0;\
    uint32 inner_macda_en=0;\
    uint32 inner_macsa_en=0;\
    lable_en = GetIpeHashCtl0(V, hashTemplate3Bulk13IsMplsLabel_f,&hash_ctl);\
    cmd = DRV_IOR(ParserMplsCtl_t, ParserMplsCtl_mplsMacDaHashEn_f);\
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd,&inner_macda_en));\
    cmd = DRV_IOR(ParserMplsCtl_t, ParserMplsCtl_mplsMacSaHashEn_f);\
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd,&inner_macsa_en));\
    if(CTC_FLAG_ISSET(flag, 0x2000))\
    {\
        if(lable_en)\
        {\
            CTC_SET_FLAG(value,CTC_LB_HASH_FIELD_LABEL2_HI);\
        }\
        else\
        {\
            CTC_UNSET_FLAG(value,CTC_LB_HASH_FIELD_LABEL2_HI);\
            if(inner_macsa_en)\
            {\
                CTC_SET_FLAG(value,  CTC_LB_HASH_FIELD_MACSA_LO);\
                CTC_SET_FLAG(value,  CTC_LB_HASH_FIELD_MACSA_MI);\
                CTC_SET_FLAG(value,  CTC_LB_HASH_FIELD_MACSA_HI);\
            }\
            if(inner_macda_en)\
            {\
                CTC_SET_FLAG(value,  CTC_LB_HASH_FIELD_MACDA_LO);\
                CTC_SET_FLAG(value,  CTC_LB_HASH_FIELD_MACDA_MI);\
                CTC_SET_FLAG(value,  CTC_LB_HASH_FIELD_MACDA_HI);\
            }\
        }\
    }\
}while(0)

#define SYS_LB_HASH_MPLS_SET_PARSER_MODEL_IP(value, hash_ctl)  \
do                                                             \
{                                                              \
    if (CTC_FLAG_ISSET(value,CTC_LB_HASH_FIELD_IP_DA_LO) &&  \
        CTC_FLAG_ISSET(value,CTC_LB_HASH_FIELD_IP_DA_HI))     \
    {                                                         \
        SetParserMplsCtl(V,mplsIpDaHashEn_f,&hash_ctl,1);     \
    }                                                         \
    else                                                      \
    {                                                         \
        SetParserMplsCtl(V,mplsIpDaHashEn_f,&hash_ctl,0);     \
    }                                                         \
    if (CTC_FLAG_ISSET(value,CTC_LB_HASH_FIELD_IP_SA_LO) &&  \
        CTC_FLAG_ISSET(value,CTC_LB_HASH_FIELD_IP_SA_HI))     \
    {                                                         \
        SetParserMplsCtl(V,mplsIpSaHashEn_f,&hash_ctl,1);     \
    }                                                         \
    else                                                      \
    {                                                         \
        SetParserMplsCtl(V,mplsIpSaHashEn_f,&hash_ctl,0);     \
    }                                                         \
}while(0)

#define SYS_LB_HASH_DECODE_SEL_ID(ctc_sel_id, sys_sel_id, udf_profile_id) \
do { \
    (sys_sel_id) = (ctc_sel_id) >> 4; \
    (udf_profile_id) = (ctc_sel_id) & 0xf; \
}while(0)

#define SYS_LB_HASH_ENCODE_SEL_ID(ctc_sel_id, sys_sel_id, udf_profile_id) \
do { \
    ctc_sel_id = ((sys_sel_id) << 4) | ((udf_profile_id) & 0xf); \
}while(0)

#define SYS_LB_HASH_SCL_PROFILE_NUM 8

STATIC int32
_sys_tsingma_hash_config_set_udf_select(uint8 lchip, ctc_lb_hash_config_t* p_hash_cfg)
{
    uint32 cmd = 0;
    uint8 step = 0;
    uint8 mask[16] = {0};
    uint8 sel_id = 0;
    uint8 udf_profile_id = 0;

    SYS_LB_HASH_DECODE_SEL_ID(p_hash_cfg->sel_id, sel_id, udf_profile_id);
    sel_id = SYS_LB_HASH_IS_COMPATIBLE_MODE ? sel_id * 2 : sel_id;

    if(DRV_FROM_TMM(lchip))
    {
        IpeLkpManagerHashBulkBitmapCtl_m lkp_hash_ctl;

        sal_memset(&lkp_hash_ctl, 0, sizeof(lkp_hash_ctl));
        sal_memset(mask,0xff,sizeof(mask));
        step = IpeLkpManagerHashBulkBitmapCtl_array_1_bulkBitmap_f - IpeLkpManagerHashBulkBitmapCtl_array_0_bulkBitmap_f;

        cmd = DRV_IOR(IpeLkpManagerHashBulkBitmapCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, udf_profile_id, cmd, &lkp_hash_ctl));

        SetIpeLkpManagerHashBulkBitmapCtl(A, udfHashBitMask_f, &lkp_hash_ctl, mask);
        SetIpeLkpManagerHashBulkBitmapCtl(V, array_0_bulkMaskValid_f + step * sel_id, &lkp_hash_ctl, 1);
        SetIpeLkpManagerHashBulkBitmapCtl(V, array_0_forceFullUdfKey_f + step * sel_id, &lkp_hash_ctl, 1);
        SetIpeLkpManagerHashBulkBitmapCtl(V, array_0_bulkBitmap_f + step * sel_id, &lkp_hash_ctl, p_hash_cfg->value);
        if (MCHIP_CAP(SYS_CAP_LB_HASH_SELECT_NUM) == SYS_USW_LB_HASH_CTL_NUM)
        {
            SetIpeLkpManagerHashBulkBitmapCtl(V, array_0_bulkMaskValid_f + step * (sel_id + 1), &lkp_hash_ctl, 1);
            SetIpeLkpManagerHashBulkBitmapCtl(V, array_0_forceFullUdfKey_f + step * (sel_id + 1), &lkp_hash_ctl, 1);
            SetIpeLkpManagerHashBulkBitmapCtl(V, array_0_bulkBitmap_f + step * (sel_id + 1), &lkp_hash_ctl, p_hash_cfg->value);
        }

        cmd = DRV_IOW(IpeLkpManagerHashBulkBitmapCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, udf_profile_id, cmd, &lkp_hash_ctl));
    }
    else
    {
        IpeSclFlowHashBulkBitmapCtl_m hash_ctl;
        sal_memset(&hash_ctl, 0, sizeof(hash_ctl));

        cmd = DRV_IOR(IpeSclFlowHashBulkBitmapCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hash_ctl));

        step  = (IpeSclFlowHashBulkBitmapCtl_array_1_userHashSelector0BulkBitmap_f -
                 IpeSclFlowHashBulkBitmapCtl_array_0_userHashSelector0BulkBitmap_f) * udf_profile_id +
                (IpeSclFlowHashBulkBitmapCtl_array_0_userHashSelector1BulkBitmap_f -
                 IpeSclFlowHashBulkBitmapCtl_array_0_userHashSelector0BulkBitmap_f) * sel_id;

        SetIpeSclFlowHashBulkBitmapCtl(V, array_0_userHashSelector0BulkMaskValid_f + step, &hash_ctl, 1);
        SetIpeSclFlowHashBulkBitmapCtl(V, array_0_userHashSelector0ForceUdfKey_f + step, &hash_ctl, 1);
        SetIpeSclFlowHashBulkBitmapCtl(V, array_0_userHashSelector0BulkBitmap_f + step, &hash_ctl, p_hash_cfg->value);

        cmd = DRV_IOW(IpeSclFlowHashBulkBitmapCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hash_ctl));
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_hash_config_get_udf_select(uint8 lchip, ctc_lb_hash_config_t* p_hash_cfg)
{
    uint32 cmd = 0;
    uint8 step = 0;
    uint8 sel_id = 0;
    uint8 udf_profile_id = 0;

    SYS_LB_HASH_DECODE_SEL_ID(p_hash_cfg->sel_id, sel_id, udf_profile_id);
    sel_id = SYS_LB_HASH_IS_COMPATIBLE_MODE ? sel_id * 2 : sel_id;

    if(DRV_FROM_TMM(lchip))
    {
        IpeLkpManagerHashBulkBitmapCtl_m lkp_hash_ctl;

        sal_memset(&lkp_hash_ctl, 0, sizeof(lkp_hash_ctl));
        step = (IpeLkpManagerHashBulkBitmapCtl_array_1_bulkBitmap_f -
                IpeLkpManagerHashBulkBitmapCtl_array_0_bulkBitmap_f) * sel_id;

        cmd = DRV_IOR(IpeLkpManagerHashBulkBitmapCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, udf_profile_id, cmd, &lkp_hash_ctl));

        p_hash_cfg->value = GetIpeLkpManagerHashBulkBitmapCtl(V, array_0_bulkBitmap_f + step, &lkp_hash_ctl);
    }
    else
    {
        IpeSclFlowHashBulkBitmapCtl_m hash_ctl;
        sal_memset(&hash_ctl, 0, sizeof(hash_ctl));
        cmd = DRV_IOR(IpeSclFlowHashBulkBitmapCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hash_ctl));

        step  = (IpeSclFlowHashBulkBitmapCtl_array_1_userHashSelector0BulkBitmap_f -
                 IpeSclFlowHashBulkBitmapCtl_array_0_userHashSelector0BulkBitmap_f) * udf_profile_id +
                (IpeSclFlowHashBulkBitmapCtl_array_0_userHashSelector1BulkBitmap_f -
                 IpeSclFlowHashBulkBitmapCtl_array_0_userHashSelector0BulkBitmap_f) * sel_id;

        p_hash_cfg->value = GetIpeSclFlowHashBulkBitmapCtl(V, array_0_userHashSelector0BulkBitmap_f + step, &hash_ctl);
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_hash_config_set_hash_select(uint8 lchip, ctc_lb_hash_config_t* p_hash_cfg)
{
    IpeHashCtl0_m hash_ctl;
    ParserMplsCtl_m parser_mpls_ctl;
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32 flag = 0;
    uint8 mode = 0;
    uint8 flow_label_en = 0;
    uint8 mpls_label_en = 0;
    uint8 index = SYS_LB_HASH_IS_COMPATIBLE_MODE ? p_hash_cfg->sel_id * 2 : p_hash_cfg->sel_id;

    if (MCHIP_HASH(lchip)->set_mask_profile_en)
    {
        MCHIP_HASH(lchip)->set_mask_profile_en(lchip, p_hash_cfg->sel_id, 0);
    }

    sal_memset(&hash_ctl, 0, sizeof(hash_ctl));
    cmd = DRV_IOR(IpeHashCtl0_t + index, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hash_ctl));

    sal_memset(&parser_mpls_ctl, 0, sizeof(parser_mpls_ctl));
    cmd = DRV_IOR(ParserMplsCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &parser_mpls_ctl));

    flow_label_en = GetIpeHashCtl0(V, ipv4PayloadIsV6UseFlowLabel_f, &hash_ctl);
    mpls_label_en = GetIpeHashCtl0(V, hashTemplate3Bulk13IsMplsLabel_f, &hash_ctl);

    switch (p_hash_cfg->hash_select)
    {
            /*L2 header hash */
        case CTC_LB_HASH_SELECT_L2:
            HASH_KEY_TEMPLATE0(flag, p_hash_cfg->value, 0);
            SetIpeHashCtl0(V, outerL2BulkBitmap_f, &hash_ctl, flag);
            SetIpeHashCtl0(V, ipv4InnerL2BulkBitmap_f, &hash_ctl, flag);
            SetIpeHashCtl0(V, ipv6InnerL2BulkBitmap_f, &hash_ctl, flag);
            SetIpeHashCtl0(V, defaultBulkBitmap_f, &hash_ctl, flag);
            break;

            /*ipv4 header hash */
        case CTC_LB_HASH_SELECT_IPV4:
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, 0);
            SetIpeHashCtl0(V, ipv4InnerL3BulkBitmap0_f, &hash_ctl, flag);
            SetIpeHashCtl0(V, ipv4OuterL3BulkBitmap_f, &hash_ctl, flag);
            SetIpeHashCtl0(V, ipv6InnerL3BulkBitmap0_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_IPV4_TCP_UDP:
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, 0);
            SetIpeHashCtl0(V, ipv4TcpUdpBulkBitmap1_f, &hash_ctl, flag);
            SetIpeHashCtl0(V, ipv6TcpUdpBulkBitmap3_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_IPV4_TCP_UDP_PORTS_EQUAL:
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, 0);
            SetIpeHashCtl0(V, ipv4TcpUdpBulkBitmap0_f, &hash_ctl, flag);
            SetIpeHashCtl0(V, ipv6TcpUdpBulkBitmap2_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_IPV4_VXLAN:
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, 1);
            SetIpeHashCtl0(V, ipv4VxlanBulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_IPV4_GRE:
            HASH_KEY_TEMPLATE5(flag, p_hash_cfg->value, 0);
            SetIpeHashCtl0(V, ipv4GreBulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_IPV4_NVGRE:
            HASH_KEY_TEMPLATE5(flag, p_hash_cfg->value, 1);
            SetIpeHashCtl0(V, ipv4NvgreBulkBitmap_f, &hash_ctl, flag);
            break;

            /*ipv6 header hash */
        case CTC_LB_HASH_SELECT_IPV6:
            mode = flow_label_en ? 2:0;
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            SetIpeHashCtl0(V, ipv4InnerL3BulkBitmap1_f, &hash_ctl, flag);
            SetIpeHashCtl0(V, ipv6InnerL3BulkBitmap1_f, &hash_ctl, flag);
            SetIpeHashCtl0(V, ipv6OuterL3BulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_IPV6_TCP_UDP:
            mode = flow_label_en ? 2:0;
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            SetIpeHashCtl0(V, ipv4TcpUdpBulkBitmap3_f, &hash_ctl, flag);
            SetIpeHashCtl0(V, ipv6TcpUdpBulkBitmap1_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_IPV6_TCP_UDP_PORTS_EQUAL:
            mode = flow_label_en ? 2:0;
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            SetIpeHashCtl0(V, ipv4TcpUdpBulkBitmap2_f, &hash_ctl, flag);
            SetIpeHashCtl0(V, ipv6TcpUdpBulkBitmap0_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_IPV6_VXLAN:
            mode = flow_label_en ? 2:1;
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            SetIpeHashCtl0(V, ipv6VxlanBulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_IPV6_GRE:
            mode = flow_label_en ? 2:0;
            HASH_KEY_TEMPLATE5(flag, p_hash_cfg->value, mode);
            SetIpeHashCtl0(V, ipv6GreBulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_IPV6_NVGRE:
            mode = flow_label_en ? 3:1;
            HASH_KEY_TEMPLATE5(flag, p_hash_cfg->value, mode);
            SetIpeHashCtl0(V, ipv6NvgreBulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_NVGRE_INNER_L2:
            HASH_KEY_TEMPLATE0(flag, p_hash_cfg->value, 1);
            SetIpeHashCtl0(V, nvgreInnerL2BulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_NVGRE_INNER_IPV4:
            mode = DRV_FROM_TMM(lchip) ? 1 : 8;
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            SetIpeHashCtl0(V, nvgreInnerL3BulkBitmap0_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_NVGRE_INNER_IPV6:
            if (DRV_FROM_TMM(lchip))
            {
                mode = flow_label_en ? 2 : 1;
            }
            else
            {
                mode = flow_label_en ? 10 : 8;
            }
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            SetIpeHashCtl0(V, nvgreInnerL3BulkBitmap1_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_VXLAN_INNER_L2:
            HASH_KEY_TEMPLATE0(flag, p_hash_cfg->value, 1);
            SetIpeHashCtl0(V, vxlanInnerL2BulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_VXLAN_INNER_IPV4:
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, 1);
            SetIpeHashCtl0(V, vxlanInnerL3BulkBitmap0_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_VXLAN_INNER_IPV6:
            mode = flow_label_en ? 2:1;
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            SetIpeHashCtl0(V, vxlanInnerL3BulkBitmap1_f, &hash_ctl, flag);
            break;

            /*mpls header hash */
        case CTC_LB_HASH_SELECT_MPLS:
            if (!DRV_FROM_TMM(lchip))
            {
                HASH_KEY_TEMPLATE3(flag, p_hash_cfg->value, 0);
                SYS_LB_HASH_MPLS_SET_PARSER_MODEL_IP(p_hash_cfg->value, parser_mpls_ctl);
                SYS_LB_HASH_MPLS_SET_INNER_MAC(p_hash_cfg->value, parser_mpls_ctl);
                SetIpeHashCtl0(V, mplsTransitInnerL3IpBulkBitmap_f, &hash_ctl, flag);
                SetIpeHashCtl0(V, mplsTransitInnerOthersBulkBitmap_f, &hash_ctl, flag);
            }
            else
            {
                HASH_KEY_TEMPLATE3(flag, p_hash_cfg->value, 0);/*outer only use label*/
                SetIpeHashCtl0(V, mplsTransitBulkBitmap_f, &hash_ctl, flag);
                mode = mpls_label_en == 0 ? 1 : 0;
                HASH_KEY_TEMPLATE3(flag, p_hash_cfg->value, mode);/*inner can use label or mac*/
                SetIpeHashCtl0(V, mplsTransitInnerOthersBulkBitmap_f, &hash_ctl, flag);
            }
            break;
        case CTC_LB_HASH_SELECT_MPLS_INNER_IPV4:
            mode = (mpls_label_en == 0 && DRV_FROM_TMM(lchip))? 1 : 0;
            HASH_KEY_TEMPLATE3(flag, p_hash_cfg->value, mode);
            if (!DRV_FROM_TMM(lchip))
            {
                SYS_LB_HASH_MPLS_SET_PARSER_MODEL_IP(p_hash_cfg->value, parser_mpls_ctl);
                SYS_LB_HASH_MPLS_SET_INNER_MAC(p_hash_cfg->value, parser_mpls_ctl);
            }
            SetIpeHashCtl0(V, mplsTransitInnerL3Ipv4BulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_MPLS_INNER_IPV6:
            mode = (mpls_label_en == 0 && DRV_FROM_TMM(lchip))? 1 : 0;
            HASH_KEY_TEMPLATE3(flag, p_hash_cfg->value, mode);
            if (!DRV_FROM_TMM(lchip))
            {
                SYS_LB_HASH_MPLS_SET_PARSER_MODEL_IP(p_hash_cfg->value, parser_mpls_ctl);
                SYS_LB_HASH_MPLS_SET_INNER_MAC(p_hash_cfg->value, parser_mpls_ctl);
            }
            SetIpeHashCtl0(V, mplsTransitInnerL3Ipv6BulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_MPLS_VPWS_RAW:
            HASH_KEY_TEMPLATE3(flag, p_hash_cfg->value, 0);
            if (!DRV_FROM_TMM(lchip))
            {
                SYS_LB_HASH_MPLS_SET_INNER_MAC(p_hash_cfg->value, parser_mpls_ctl);
            }
            SetIpeHashCtl0(V, mplsL2VpnDecapsBypassInnerParserBulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_MPLS_L2VPN_INNER_L2:
            HASH_KEY_TEMPLATE0(flag, p_hash_cfg->value, 0);
            SetIpeHashCtl0(V, mplsL2VpnDecapsInnerL2BulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_MPLS_L2VPN_INNER_IPV4:
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, 0);
            SetIpeHashCtl0(V, mplsL2VpnDecapsInnerL3Ipv4BulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_MPLS_L2VPN_INNER_IPV6:
            mode = flow_label_en ? 2:0;
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            SetIpeHashCtl0(V, mplsL2VpnDecapsInnerL3Ipv6BulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_MPLS_L3VPN_INNER_IPV4:
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, 0);
            SetIpeHashCtl0(V, mplsL3VpnDecapsInnerL3Ipv4BulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_MPLS_L3VPN_INNER_IPV6:
            mode = flow_label_en ? 2:0;
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            SetIpeHashCtl0(V, mplsL3VpnDecapsInnerL3Ipv6BulkBitmap_f, &hash_ctl, flag);
            break;

            /*trill header hash */
        case CTC_LB_HASH_SELECT_TRILL_OUTER_L2_ONLY:
            HASH_KEY_TEMPLATE0(flag, p_hash_cfg->value, 0);
            SetIpeHashCtl0(V, trillTransitOuterL2HashBulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_TRILL:
            HASH_KEY_TEMPLATE1(flag, p_hash_cfg->value);
            SetIpeHashCtl0(V, trillTransitTunnelHashBulkBitmap1_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_TRILL_INNER_L2:
            HASH_KEY_TEMPLATE1(flag, p_hash_cfg->value);
            SetIpeHashCtl0(V, trillTransitTunnelHashBulkBitmap0_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_TRILL_INNER_IPV4:
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, 0);
            SetIpeHashCtl0(V, trillTransitInnerL3Ipv4HashBulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_TRILL_INNER_IPV6:
            mode = flow_label_en ? 2:0;
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            SetIpeHashCtl0(V, trillTransitInnerL3Ipv6HashBulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_TRILL_DECAP_INNER_L2:
            HASH_KEY_TEMPLATE0(flag, p_hash_cfg->value, 0);
            SetIpeHashCtl0(V, trillTerminateInnerL2HashBulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_TRILL_DECAP_INNER_IPV4:
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, 0);
            SetIpeHashCtl0(V, trillTerminateInnerL3Ipv4HashBulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_TRILL_DECAP_INNER_IPV6:
            mode = flow_label_en ? 2:0;
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            SetIpeHashCtl0(V, trillTerminateInnerL3Ipv6HashBulkBitmap_f, &hash_ctl, flag);
            break;

            /*fcoe heaer hash */
        case CTC_LB_HASH_SELECT_FCOE:
            HASH_KEY_TEMPLATE2(flag, p_hash_cfg->value);
            SetIpeHashCtl0(V, fcoeBulkBitmap_f, &hash_ctl, flag);
            break;


            /*flex tunnel heaer hash */
        case CTC_LB_HASH_SELECT_FLEX_TNL_INNER_L2:
            HASH_KEY_TEMPLATE0(flag, p_hash_cfg->value, 0);
            SetIpeHashCtl0(V, unknownInnerL2BulkBitmap_f, &hash_ctl, flag);
            break;
        case CTC_LB_HASH_SELECT_FLEX_TNL_INNER_IPV4:
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, 0);
            SetIpeHashCtl0(V, unknownInnerIpBulkBitmap_f, &hash_ctl, flag);
            break;

        case CTC_LB_HASH_SELECT_FLEX_TNL_INNER_IPV6:
            mode = flow_label_en ? 2:0;
            HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            SetIpeHashCtl0(V, unknownInnerIpv6BulkBitmap_f, &hash_ctl, flag);
            break;

        default:
            return CTC_E_INVALID_PARAM;
    }

    cmd = DRV_IOW(IpeHashCtl0_t + index, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hash_ctl));

    if(SYS_LB_HASH_IS_COMPATIBLE_MODE)
    {
        uint32 field_id = (p_hash_cfg->sel_id / 2 == 0) ? IpeHashCtl1_hashPolySelectA_f : IpeHashCtl5_hashPolySelectA_f;
        cmd = DRV_IOR(IpeHashCtl0_t + index + 1, field_id);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));

        SetIpeHashCtl0(V, hashPolySelectA_f, &hash_ctl, field_val);
        cmd = DRV_IOW(IpeHashCtl0_t + index + 1, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hash_ctl));
    }
    cmd = DRV_IOW(ParserMplsCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &parser_mpls_ctl));

    return CTC_E_NONE;
}


STATIC int32
_sys_tsingma_hash_config_get_hash_select(uint8 lchip, ctc_lb_hash_config_t* p_hash_cfg)
{
    IpeHashCtl0_m hash_ctl;
    uint32 cmd = 0;
    uint32 flag = 0;
    uint8 mode = 0;
    uint8 flow_label_en = 0;
    uint8 mpls_label_en = 0;
    uint8 index = SYS_LB_HASH_IS_COMPATIBLE_MODE ? p_hash_cfg->sel_id * 2 : p_hash_cfg->sel_id;

    sal_memset(&hash_ctl, 0, sizeof(hash_ctl));
    cmd = DRV_IOR(IpeHashCtl0_t + index, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hash_ctl));
    p_hash_cfg->value = 0;

    flow_label_en = GetIpeHashCtl0(V, ipv4PayloadIsV6UseFlowLabel_f, &hash_ctl);
    mpls_label_en = GetIpeHashCtl0(V, hashTemplate3Bulk13IsMplsLabel_f, &hash_ctl);

    switch (p_hash_cfg->hash_select)
    {
            /*L2 header hash */
        case CTC_LB_HASH_SELECT_L2:
            flag = GetIpeHashCtl0(V, outerL2BulkBitmap_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE0(flag, p_hash_cfg->value, 0);
            break;

            /*ipv4 header hash */
        case CTC_LB_HASH_SELECT_IPV4:
            flag = GetIpeHashCtl0(V, ipv4InnerL3BulkBitmap0_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, 0);
            break;
        case CTC_LB_HASH_SELECT_IPV4_TCP_UDP:
            flag = GetIpeHashCtl0(V, ipv4TcpUdpBulkBitmap1_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, 0);
            break;
        case CTC_LB_HASH_SELECT_IPV4_TCP_UDP_PORTS_EQUAL:
            flag = GetIpeHashCtl0(V, ipv4TcpUdpBulkBitmap0_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, 0);
            break;
        case CTC_LB_HASH_SELECT_IPV4_VXLAN:
            flag = GetIpeHashCtl0(V, ipv4VxlanBulkBitmap_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, 1);
            break;
        case CTC_LB_HASH_SELECT_IPV4_GRE:
            flag = GetIpeHashCtl0(V, ipv4GreBulkBitmap_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE5(flag, p_hash_cfg->value, 0);
            break;
        case CTC_LB_HASH_SELECT_IPV4_NVGRE:
            flag = GetIpeHashCtl0(V, ipv4NvgreBulkBitmap_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE5(flag, p_hash_cfg->value, 1);
            break;

            /*ipv6 header hash */
        case CTC_LB_HASH_SELECT_IPV6:
            flag = GetIpeHashCtl0(V, ipv4InnerL3BulkBitmap1_f, &hash_ctl);
            mode = flow_label_en ? 2:0;
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            break;
        case CTC_LB_HASH_SELECT_IPV6_TCP_UDP:
            flag = GetIpeHashCtl0(V, ipv4TcpUdpBulkBitmap3_f, &hash_ctl);
            mode = flow_label_en ? 2:0;
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            break;
        case CTC_LB_HASH_SELECT_IPV6_TCP_UDP_PORTS_EQUAL:
            flag = GetIpeHashCtl0(V, ipv4TcpUdpBulkBitmap2_f, &hash_ctl);
            mode = flow_label_en ? 2:0;
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            break;
        case CTC_LB_HASH_SELECT_IPV6_VXLAN:
            flag = GetIpeHashCtl0(V, ipv6VxlanBulkBitmap_f, &hash_ctl);
            mode = flow_label_en ? 2:1;
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            break;
        case CTC_LB_HASH_SELECT_IPV6_GRE:
            flag = GetIpeHashCtl0(V, ipv6GreBulkBitmap_f, &hash_ctl);
            mode = flow_label_en ? 2:0;
            GET_HASH_KEY_TEMPLATE5(flag, p_hash_cfg->value, mode);
            break;
        case CTC_LB_HASH_SELECT_IPV6_NVGRE:
            flag = GetIpeHashCtl0(V, ipv6NvgreBulkBitmap_f, &hash_ctl);
            mode = flow_label_en ? 3:1;
            GET_HASH_KEY_TEMPLATE5(flag, p_hash_cfg->value, mode);
            break;
        case CTC_LB_HASH_SELECT_NVGRE_INNER_L2:
            flag = GetIpeHashCtl0(V, nvgreInnerL2BulkBitmap_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE0(flag, p_hash_cfg->value, 1);
            break;
        case CTC_LB_HASH_SELECT_NVGRE_INNER_IPV4:
            flag = GetIpeHashCtl0(V, nvgreInnerL3BulkBitmap0_f, &hash_ctl);
            mode = DRV_FROM_TMM(lchip) ? 1 : 8;
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            break;
        case CTC_LB_HASH_SELECT_NVGRE_INNER_IPV6:
            flag = GetIpeHashCtl0(V, nvgreInnerL3BulkBitmap1_f, &hash_ctl);
            if (DRV_FROM_TMM(lchip))
            {
                mode = flow_label_en ? 2 : 1;
            }
            else
            {
                mode = flow_label_en ? 10 : 8;
            }
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            break;
        case CTC_LB_HASH_SELECT_VXLAN_INNER_L2:
            flag = GetIpeHashCtl0(V, vxlanInnerL2BulkBitmap_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE0(flag, p_hash_cfg->value, 1);
            break;
        case CTC_LB_HASH_SELECT_VXLAN_INNER_IPV4:
            flag = GetIpeHashCtl0(V, vxlanInnerL3BulkBitmap0_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, 1);
            break;
        case CTC_LB_HASH_SELECT_VXLAN_INNER_IPV6:
            flag = GetIpeHashCtl0(V, vxlanInnerL3BulkBitmap1_f, &hash_ctl);
            mode = flow_label_en ? 2:1;
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            break;

            /*mpls header hash */
        case CTC_LB_HASH_SELECT_MPLS:
            flag = GetIpeHashCtl0(V, mplsTransitInnerOthersBulkBitmap_f, &hash_ctl);
            mode = (mpls_label_en == 0 && DRV_FROM_TMM(lchip)) ? 1 : 0;
            GET_HASH_KEY_TEMPLATE3(flag, p_hash_cfg->value, mode);
            if (!DRV_FROM_TMM(lchip))
            {
                SYS_LB_HASH_MPLS_GET_INNER_MAC(flag, p_hash_cfg->value, hash_ctl);
            }
            else
            {
                flag = GetIpeHashCtl0(V, mplsTransitBulkBitmap_f, &hash_ctl);
                GET_HASH_KEY_TEMPLATE3(flag, p_hash_cfg->value, 0);
            }
            break;
        case CTC_LB_HASH_SELECT_MPLS_INNER_IPV4:
            flag = GetIpeHashCtl0(V, mplsTransitInnerL3Ipv4BulkBitmap_f, &hash_ctl);
            mode = (mpls_label_en == 0 && DRV_FROM_TMM(lchip))? 1 : 0;

            GET_HASH_KEY_TEMPLATE3(flag, p_hash_cfg->value, mode);
            if (!DRV_FROM_TMM(lchip))
            {
                SYS_LB_HASH_MPLS_GET_INNER_MAC(flag, p_hash_cfg->value, hash_ctl);
            }
            break;
        case CTC_LB_HASH_SELECT_MPLS_INNER_IPV6:
            flag = GetIpeHashCtl0(V, mplsTransitInnerL3Ipv6BulkBitmap_f, &hash_ctl);
            mode = (mpls_label_en == 0 && DRV_FROM_TMM(lchip))? 1 : 0;

            GET_HASH_KEY_TEMPLATE3(flag, p_hash_cfg->value, mode);
            if (!DRV_FROM_TMM(lchip))
            {
                SYS_LB_HASH_MPLS_GET_INNER_MAC(flag, p_hash_cfg->value, hash_ctl);
            }
            break;
        case CTC_LB_HASH_SELECT_MPLS_VPWS_RAW:
            flag = GetIpeHashCtl0(V, mplsL2VpnDecapsBypassInnerParserBulkBitmap_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE3(flag, p_hash_cfg->value, 0);
            if (!DRV_FROM_TMM(lchip))
            {
                SYS_LB_HASH_MPLS_GET_INNER_MAC(flag, p_hash_cfg->value, hash_ctl);
            }
            break;
        case CTC_LB_HASH_SELECT_MPLS_L2VPN_INNER_L2:
            flag = GetIpeHashCtl0(V, mplsL2VpnDecapsInnerL2BulkBitmap_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE0(flag, p_hash_cfg->value, 0);
            break;
        case CTC_LB_HASH_SELECT_MPLS_L2VPN_INNER_IPV4:
            flag = GetIpeHashCtl0(V, mplsL2VpnDecapsInnerL3Ipv4BulkBitmap_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, 0);
            break;
        case CTC_LB_HASH_SELECT_MPLS_L2VPN_INNER_IPV6:
            flag = GetIpeHashCtl0(V, mplsL2VpnDecapsInnerL3Ipv6BulkBitmap_f, &hash_ctl);
            mode = flow_label_en ? 2 : 0;
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            break;
        case CTC_LB_HASH_SELECT_MPLS_L3VPN_INNER_IPV4:
            flag = GetIpeHashCtl0(V, mplsL3VpnDecapsInnerL3Ipv4BulkBitmap_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, 0);
            break;
        case CTC_LB_HASH_SELECT_MPLS_L3VPN_INNER_IPV6:
            flag = GetIpeHashCtl0(V, mplsL3VpnDecapsInnerL3Ipv6BulkBitmap_f, &hash_ctl);
            mode = flow_label_en ? 2 : 0;
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            break;

            /*trill header hash */
        case CTC_LB_HASH_SELECT_TRILL_OUTER_L2_ONLY:
            flag = GetIpeHashCtl0(V, trillTransitOuterL2HashBulkBitmap_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE0(flag, p_hash_cfg->value, 0);
            break;
        case CTC_LB_HASH_SELECT_TRILL:
            flag = GetIpeHashCtl0(V, trillTransitTunnelHashBulkBitmap1_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE1(flag, p_hash_cfg->value);
            break;
        case CTC_LB_HASH_SELECT_TRILL_INNER_L2:
            flag = GetIpeHashCtl0(V, trillTransitTunnelHashBulkBitmap0_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE1(flag, p_hash_cfg->value);
            break;
        case CTC_LB_HASH_SELECT_TRILL_INNER_IPV4:
            flag = GetIpeHashCtl0(V, trillTransitInnerL3Ipv4HashBulkBitmap_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, 0);
            break;
        case CTC_LB_HASH_SELECT_TRILL_INNER_IPV6:
            flag = GetIpeHashCtl0(V, trillTransitInnerL3Ipv6HashBulkBitmap_f, &hash_ctl);
            mode = flow_label_en ? 2:0;
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            break;
        case CTC_LB_HASH_SELECT_TRILL_DECAP_INNER_L2:
            flag = GetIpeHashCtl0(V, trillTerminateInnerL2HashBulkBitmap_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE0(flag, p_hash_cfg->value, 0);
            break;
        case CTC_LB_HASH_SELECT_TRILL_DECAP_INNER_IPV4:
            flag = GetIpeHashCtl0(V, trillTerminateInnerL3Ipv4HashBulkBitmap_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, 0);
            break;
        case CTC_LB_HASH_SELECT_TRILL_DECAP_INNER_IPV6:
            flag = GetIpeHashCtl0(V, trillTerminateInnerL3Ipv6HashBulkBitmap_f, &hash_ctl);
            mode = flow_label_en ? 2:0;
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            break;

            /*fcoe heaer hash */
        case CTC_LB_HASH_SELECT_FCOE:
            flag = GetIpeHashCtl0(V, fcoeBulkBitmap_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE2(flag, p_hash_cfg->value);
            break;

            /*flex tunnel heaer hash */
        case CTC_LB_HASH_SELECT_FLEX_TNL_INNER_L2:
            flag = GetIpeHashCtl0(V, unknownInnerL2BulkBitmap_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE0(flag, p_hash_cfg->value, 0);
            break;

        case CTC_LB_HASH_SELECT_FLEX_TNL_INNER_IPV4:
            flag = GetIpeHashCtl0(V, unknownInnerIpBulkBitmap_f, &hash_ctl);
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, 0);
            break;

        case CTC_LB_HASH_SELECT_FLEX_TNL_INNER_IPV6:
            flag = GetIpeHashCtl0(V, unknownInnerIpv6BulkBitmap_f, &hash_ctl);
            mode = flow_label_en ? 2:0;
            GET_HASH_KEY_TEMPLATE4(flag, p_hash_cfg->value, mode);
            break;

        default:
            return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}


int32 
_sys_tsingma_map_hash_udf_sel_mode(uint8 lchip, uint32 ctc_mode, uint32* sys_mode)
{
    uint8 hash_udf_sel_map[CTC_LB_HASH_UDF_SEL_MAX_MODE] = {7,6,5,0,3,2,1,4,1};
    *sys_mode = 0xff;
    if(DRV_FROM_TMM(lchip))
    {
        if(ctc_mode > CTC_LB_HASH_UDF_SEL_MODE3 && ctc_mode < CTC_LB_HASH_UDF_SEL_MODE8)
        {
            return CTC_E_NOT_SUPPORT;
        }
        *sys_mode = (ctc_mode == CTC_LB_HASH_UDF_SEL_MODE8) ? 4: ctc_mode;
    }
    else
    {
        if (ctc_mode==CTC_LB_HASH_UDF_SEL_MODE8 && (!(SYS_GET_CHIP_VERSION != SYS_CHIP_SUB_VERSION_A) && DRV_IS_TSINGMA(lchip)) )
        {
            return CTC_E_NOT_SUPPORT;
        }
        *sys_mode = hash_udf_sel_map[ctc_mode];
    }
    return CTC_E_NONE;
}

int32
_sys_tsingma_hash_config_set_hash_control(uint8 lchip, ctc_lb_hash_config_t* p_hash_cfg)
{
    IpeHashCtl0_m hash_ctl;
    uint32 cmd = 0;
    uint32 value = 0;
    uint32 step  = 0;
    uint8 index = SYS_LB_HASH_IS_COMPATIBLE_MODE ? p_hash_cfg->sel_id * 2 : p_hash_cfg->sel_id;

    sal_memset(&hash_ctl, 0, sizeof(hash_ctl));
    cmd = DRV_IOR(IpeHashCtl0_t + index, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hash_ctl));

    switch (p_hash_cfg->hash_control)
    {
        case CTC_LB_HASH_CONTROL_L2_ONLY:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, disableIpv4Hash_f, &hash_ctl, value);
            SetIpeHashCtl0(V, disableIpv6Hash_f, &hash_ctl, value);
            SetIpeHashCtl0(V, disableMplsHash_f, &hash_ctl, value);
            SetIpeHashCtl0(V, disableFcoeHash_f, &hash_ctl, value);
            SetIpeHashCtl0(V, disableTrillHash_f, &hash_ctl, value);
            SetIpeHashCtl0(V, v4TunnelDisableIpv4Hash_f, &hash_ctl, (value?0x3F:0));
            SetIpeHashCtl0(V, v6TunnelDisableIpv6Hash_f, &hash_ctl, (value?0x3F:0));
            SetIpeHashCtl0(V, mplsTunnelDisableMplsHash_f, &hash_ctl, (value?0xF:0));
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_IPV4:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, disableIpv4Hash_f, &hash_ctl, value);
            SetIpeHashCtl0(V, v4TunnelDisableIpv4Hash_f, &hash_ctl, (value?0x3F:0));
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_IPV6:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, disableIpv6Hash_f, &hash_ctl, value);
            SetIpeHashCtl0(V, v6TunnelDisableIpv6Hash_f, &hash_ctl, (value?0x3F:0));
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_MPLS:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, disableMplsHash_f, &hash_ctl, value);
            SetIpeHashCtl0(V, mplsTunnelDisableMplsHash_f, &hash_ctl, (value?0xF:0));
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_FCOE:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, disableFcoeHash_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TRILL:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, disableTrillHash_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TUNNEL_IPV4_IN4:
            value = GetIpeHashCtl0(V, ipv4EnableInnerHashTunnelBitmap_f, &hash_ctl);
            p_hash_cfg->value ? CTC_BIT_UNSET(value, 2) : CTC_BIT_SET(value, 2);
            SetIpeHashCtl0(V, ipv4EnableInnerHashTunnelBitmap_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TUNNEL_IPV6_IN4:
            value = GetIpeHashCtl0(V, ipv4EnableInnerHashTunnelBitmap_f, &hash_ctl);
            p_hash_cfg->value ? CTC_BIT_UNSET(value, 1) : CTC_BIT_SET(value, 1);
            SetIpeHashCtl0(V, ipv4EnableInnerHashTunnelBitmap_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TUNNEL_GRE_IN4:
            value = GetIpeHashCtl0(V, ipv4EnableInnerHashTunnelBitmap_f, &hash_ctl);
            p_hash_cfg->value ? CTC_BIT_UNSET(value, 3) : CTC_BIT_SET(value, 3);
            SetIpeHashCtl0(V, ipv4EnableInnerHashTunnelBitmap_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TUNNEL_NVGRE_IN4:
            value = GetIpeHashCtl0(V, ipv4EnableInnerHashTunnelBitmap_f, &hash_ctl);
            p_hash_cfg->value ? CTC_BIT_UNSET(value, 4) : CTC_BIT_SET(value, 4);
            SetIpeHashCtl0(V, ipv4EnableInnerHashTunnelBitmap_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TUNNEL_VXLAN_IN4:
            value = GetIpeHashCtl0(V, ipv4EnableInnerHashTunnelBitmap_f, &hash_ctl);
            p_hash_cfg->value ? CTC_BIT_UNSET(value, 5) : CTC_BIT_SET(value, 5);
            SetIpeHashCtl0(V, ipv4EnableInnerHashTunnelBitmap_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TUNNEL_IPV4_IN6:
            value = GetIpeHashCtl0(V, ipv6EnableInnerHashTunnelBitmap_f, &hash_ctl);
            p_hash_cfg->value ? CTC_BIT_UNSET(value, 2) : CTC_BIT_SET(value, 2);
            SetIpeHashCtl0(V, ipv6EnableInnerHashTunnelBitmap_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TUNNEL_IPV6_IN6:
            value = GetIpeHashCtl0(V, ipv6EnableInnerHashTunnelBitmap_f, &hash_ctl);
            p_hash_cfg->value ? CTC_BIT_UNSET(value, 1) : CTC_BIT_SET(value, 1);
            SetIpeHashCtl0(V, ipv6EnableInnerHashTunnelBitmap_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TUNNEL_GRE_IN6:
            value = GetIpeHashCtl0(V, ipv6EnableInnerHashTunnelBitmap_f, &hash_ctl);
            p_hash_cfg->value ? CTC_BIT_UNSET(value, 3) : CTC_BIT_SET(value, 3);
            SetIpeHashCtl0(V, ipv6EnableInnerHashTunnelBitmap_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TUNNEL_NVGRE_IN6:
            value = GetIpeHashCtl0(V, ipv6EnableInnerHashTunnelBitmap_f, &hash_ctl);
            p_hash_cfg->value ? CTC_BIT_UNSET(value, 4) : CTC_BIT_SET(value, 4);
            SetIpeHashCtl0(V, ipv6EnableInnerHashTunnelBitmap_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TUNNEL_VXLAN_IN6:
            value = GetIpeHashCtl0(V, ipv6EnableInnerHashTunnelBitmap_f, &hash_ctl);
            p_hash_cfg->value ? CTC_BIT_UNSET(value, 5) : CTC_BIT_SET(value, 5);
            SetIpeHashCtl0(V, ipv6EnableInnerHashTunnelBitmap_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_MPLS_EXCLUDE_RSV:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, mplsHashSkipReservedLabel_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_IPV6_ADDR_COLLAPSE:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, ipv6AddrCompressMode_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_IPV6_USE_FLOW_LABEL:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, ipv4PayloadIsV6UseFlowLabel_f, &hash_ctl, value);
            SetIpeHashCtl0(V, bulk12And13Ipv6UseFlowLabel0_f, &hash_ctl, value);
            SetIpeHashCtl0(V, bulk12And13Ipv6UseFlowLabel1_f, &hash_ctl, value);
            SetIpeHashCtl0(V, bulk12And13Ipv6UseFlowLabel2_f, &hash_ctl, value);
            SetIpeHashCtl0(V, bulk12And13Ipv6UseFlowLabel3_f, &hash_ctl, value);
            SetIpeHashCtl0(V, bulk12And13Ipv6UseFlowLabel4_f, &hash_ctl, value);
            SetIpeHashCtl0(V, bulk12And13Ipv6UseFlowLabel5_f, &hash_ctl, value);
            SetIpeHashCtl0(V, ipv4VxlanInnerL3Bulk12Andl3UseVni_f, &hash_ctl, !value);
            SetIpeHashCtl0(V, ipv6VxlanInnerL3Bulk12Andl3UseVni_f, &hash_ctl, !value);
            SetIpeHashCtl0(V, v6VxlanOuterL3HashUdfFieldUseVni_f, &hash_ctl, !value);
            SetIpeHashCtl0(V, ipv4NvgreInnerL3Bulk12And13UseVsiId_f, &hash_ctl, !value);
            SetIpeHashCtl0(V, ipv6NvgreInnerL3Bulk12And13UseVsiId_f, &hash_ctl, !value);
            break;
        case CTC_LB_HASH_CONTROL_NVGRE_AWARE:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, awaredNvgre_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_FCOE_SYMMETRIC_EN:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, fcoeSymmetricHashEn_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_UDF_SELECT_MODE:
            {
                uint32 value = 0;
                uint32 sys_mode = 0;
                CTC_MAX_VALUE_CHECK(p_hash_cfg->value,CTC_LB_HASH_UDF_SEL_MAX_MODE -1);
                CTC_ERROR_RETURN(_sys_tsingma_map_hash_udf_sel_mode(lchip, p_hash_cfg->value, &sys_mode));
                SetIpeHashCtl0(V, udfDataSel_f, &hash_ctl, sys_mode);
                cmd = DRV_IOR(IpeLkupMgrReserved_t, IpeLkupMgrReserved_reserved_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
                (p_hash_cfg->value == CTC_LB_HASH_UDF_SEL_MODE8) ? CTC_BIT_SET(value, 2) : CTC_BIT_UNSET(value, 2);
                cmd = DRV_IOW(IpeLkupMgrReserved_t, IpeLkupMgrReserved_reserved_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
                break;
            }
        case CTC_LB_HASH_CONTROL_USE_MAPPED_VLAN:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, vidDataSel_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_IPV4_SYMMETRIC_EN:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, outerIpv4SymmetricHashEn_f, &hash_ctl, value);
            SetIpeHashCtl0(V, innerIpv4SymmetricHashEn_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_IPV6_SYMMETRIC_EN:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, outerIpv6SymmetricHashEn_f, &hash_ctl, value);
            SetIpeHashCtl0(V, innerIpv6SymmetricHashEn_f, &hash_ctl, value);
            break;

        case CTC_LB_HASH_CONTROL_L2VPN_USE_INNER_L2:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, mplsL2VpnDecapsUseInnerL2Hash_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_VPWS_USE_INNER:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, vpwsDecapsHashMode_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_TRILL_DECAP_USE_INNER_L2:
            value = p_hash_cfg->value ? 0 : 1;
            SetIpeHashCtl0(V, trillTerminateNodeHashMode_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_TRILL_TRANSMIT_MODE:
            CTC_MAX_VALUE_CHECK(p_hash_cfg->value, 3);
            SetIpeHashCtl0(V, trillTransitNodeHashMode_f, &hash_ctl, p_hash_cfg->value);
            break;
        case CTC_LB_HASH_CONTROL_MPLS_ENTROPY_EN:
            if(DRV_FROM_TMM(lchip))
            {
                return CTC_E_NOT_SUPPORT;
            }
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, mplsL2VpnDecapsVpwsUseGlobalInnerHdrHashA_f, &hash_ctl, value);
            SetIpeHashCtl0(V, mplsL2VpnDecapsVpwsUseGlobalInnerHdrHashB_f, &hash_ctl, value);
            SetIpeHashCtl0(V, mplsTransitUseGlobalInnerHdrHashA_f, &hash_ctl, value);
            SetIpeHashCtl0(V, mplsTransitUseGlobalInnerHdrHashB_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_MPLS_LABEL2_EN:
            value = p_hash_cfg->value ? 3 : 0;
            SetIpeHashCtl0(V, hashTemplate3Bulk13IsMplsLabel_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_VXLAN_USE_INNER_L2:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, vxlanInnerL2HashEn_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_NVGRE_USE_INNER_L2:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, nvGreInnerL2HashEn_f, &hash_ctl, value);
            break;
        case CTC_LB_HASH_CONTROL_FLEX_TNL_USE_INNER_L2:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, forceInnerL2HashEn_f, &hash_ctl, value);
            break;

        case CTC_LB_HASH_CONTROL_HASH_SEED:
            CTC_MAX_VALUE_CHECK(p_hash_cfg->value, 0xFFFFFFFF);
            SetIpeHashCtl0(V, hashSeed_f, &hash_ctl, p_hash_cfg->value);
            break;
        case CTC_LB_HASH_CONTROL_HASH_TYPE_A:
        case CTC_LB_HASH_CONTROL_HASH_TYPE_B:
            {
            switch (p_hash_cfg->value)
                {
                case CTC_LB_HASH_TYPE_CRC8_POLY1:
                    value = DRV_FROM_TMM(lchip) ? SYS_LB_HASHPOLY_CRC16_POLY1 : SYS_LB_HASHPOLY_CRC8_POLY1;
                    break;
                case CTC_LB_HASH_TYPE_CRC8_POLY2:
                    value = SYS_LB_HASHPOLY_CRC8_POLY2;
                    break;
                case CTC_LB_HASH_TYPE_XOR8:
                    value = SYS_LB_HASHPOLY_XOR8;
                    break;
                case CTC_LB_HASH_TYPE_CRC10_POLY1:
                    value = DRV_FROM_TMM(lchip) ? SYS_LB_HASHPOLY_CRC16_POLY1 : SYS_LB_HASHPOLY_CRC10_POLY1;
                    break;
                case CTC_LB_HASH_TYPE_CRC10_POLY2:
                    value = DRV_FROM_TMM(lchip) ? SYS_LB_HASHPOLY_CRC16_POLY1 : SYS_LB_HASHPOLY_CRC10_POLY2;
                    break;
                case CTC_LB_HASH_TYPE_XOR16:
                    value = SYS_LB_HASHPOLY_XOR16;
                    break;
                case CTC_LB_HASH_TYPE_CRC16_POLY1:
                    value = SYS_LB_HASHPOLY_CRC16_POLY1;
                    break;
                case CTC_LB_HASH_TYPE_CRC16_POLY2:
                    value = SYS_LB_HASHPOLY_CRC16_POLY2;
                    break;
                case CTC_LB_HASH_TYPE_CRC16_POLY3:
                    value = DRV_FROM_TMM(lchip) ? SYS_LB_HASHPOLY_CRC16_POLY1 : SYS_LB_HASHPOLY_CRC16_POLY3;
                    break;
                case CTC_LB_HASH_TYPE_CRC16_POLY4:
                    value = DRV_FROM_TMM(lchip) ? SYS_LB_HASHPOLY_CRC16_POLY1 : SYS_LB_HASHPOLY_CRC16_POLY4;
                    break;
                case CTC_LB_HASH_TYPE_CRC16_POLY5:
                    value = SYS_LB_HASHPOLY_CRC16_POLY5;
                    break;
                case CTC_LB_HASH_TYPE_CRC16_POLY6:
                    value = SYS_LB_HASHPOLY_CRC16_POLY6;
                    break;
                case CTC_LB_HASH_TYPE_CRC32_POLY1:
                    value = SYS_LB_HASHPOLY_CRC32_POLY1;
                    break;
                case CTC_LB_HASH_TYPE_CRC32_POLY2:
                    value = SYS_LB_HASHPOLY_CRC32_POLY2;
                    break;
                default:
                    return CTC_E_INVALID_PARAM;
                }
                (SYS_LB_HASH_IS_COMPATIBLE_MODE || p_hash_cfg->hash_control == CTC_LB_HASH_CONTROL_HASH_TYPE_A)?
                (SetIpeHashCtl0(V, hashPolySelectA_f, &hash_ctl, value)):
                (SetIpeHashCtl0(V, hashPolySelectB_f, &hash_ctl, value));
            }
            break;
            /*corresponding byte mask if set, mean that the byte don't uesed to compute hash value*/
        case CTC_LB_HASH_CONTROL_HASH_TYPE_UDF_DATA_BYTE_MASK:
            if(DRV_FROM_TMM(lchip))
            {
                uint8 udf_mask[CTC_LB_HASH_UDF_BYTE_NUM] = {0};
                uint8 index = 0;
                sal_memset(udf_mask, 0xFF, CTC_LB_HASH_UDF_BYTE_NUM);
                for (index = 0; index < CTC_LB_HASH_UDF_BYTE_NUM; index++)
                {
                    value = CTC_IS_BIT_SET(p_hash_cfg->value, index) ? 0 : 0xFF;
                    sal_memset(&udf_mask[index], value, sizeof(uint8));
                }
                cmd = DRV_IOW(IpeLkpManagerHashBulkBitmapCtl_t, IpeLkpManagerHashBulkBitmapCtl_udfHashBitMask_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, p_hash_cfg->sel_id, cmd, udf_mask));
            }
            else
            {
                value = p_hash_cfg->value;
                step =  IpeSclFlowHashBulkBitmapCtl_array_1_flexHashUdfByteMask_f - IpeSclFlowHashBulkBitmapCtl_array_0_flexHashUdfByteMask_f;
                cmd = DRV_IOW(IpeSclFlowHashBulkBitmapCtl_t, IpeSclFlowHashBulkBitmapCtl_array_0_flexHashUdfByteMask_f + step * p_hash_cfg->sel_id);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
            }
            break;
            /*corresponding bit mask if set, mean that the bit will uesed to compute hash value*/
        case CTC_LB_HASH_CONTROL_HASH_TYPE_UDF_DATA_BIT_MASK:
            cmd = DRV_IOW(IpeLkpManagerHashBulkBitmapCtl_t, IpeLkpManagerHashBulkBitmapCtl_udfHashBitMask_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, p_hash_cfg->sel_id, cmd, p_hash_cfg->udf_mask));
            break;
        case CTC_LB_HASH_CONTROL_HASH_SEED_USE_UDF:
            /*0:do not use udf,1:bucket14 and bucket15(seed),2:bucket0 and bucket1(src info),3:rsv*/
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, enableUdfMode_f, &hash_ctl, p_hash_cfg->value);
            break;
                case SYS_LB_HASH_CONTROL_L2VPN_USE_OUTER_L3:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, forceL2VpnMplsHashEn_f, &hash_ctl, value);
            break;

        case SYS_LB_HASH_CONTROL_L3VPN_USE_OUTER_L3:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, forceL3VpnMplsHashEn_f, &hash_ctl, value);
            break;

        case SYS_LB_HASH_CONTROL_MPLS_TRANSMIT_MODE:
            value = p_hash_cfg->value;
            if (DRV_FROM_AT(lchip))
            {
                CTC_MAX_VALUE_CHECK(value, 2);
            }
            else
            {
                CTC_MAX_VALUE_CHECK(value, 1);
            }
            if (0 == value) /* mac */
            {
                SetIpeHashCtl0(V, hashTemplate3Bulk13IsMplsLabel_f, &hash_ctl, 0);
                SetIpeHashCtl0(V, mplsTransitUseTemplateMode_f, &hash_ctl, 0);
            }
            else if (1 == value) /* label2 */
            {
                SetIpeHashCtl0(V, hashTemplate3Bulk13IsMplsLabel_f, &hash_ctl, 3);
                SetIpeHashCtl0(V, mplsTransitUseTemplateMode_f, &hash_ctl, 0);
            }
            else /* l4 port */
            {
                SetIpeHashCtl0(V, mplsTransitUseTemplateMode_f, &hash_ctl, 1);
                SetIpeHashCtl0(V, hashTemplate3Bulk13IsMplsLabel_f, &hash_ctl, 0);
            }
            break;
            
        case SYS_LB_HASH_CONTROL_GRE_INNER_L2_USE_VSID:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, nvgreInnerL2HashUseVsid_f, &hash_ctl, value);
            break;

        case SYS_LB_HASH_CONTROL_VXLAN_INNER_L2_USE_VNI:
            value = p_hash_cfg->value ? 1 : 0;
            SetIpeHashCtl0(V, vxlanInnerL2HashUseVni_f, &hash_ctl, value);
            break;

        case SYS_LB_HASH_CONTROL_UDF_BULK_EN:
            value = p_hash_cfg->value ? 0 : 1;
            SetIpeHashCtl0(V, ipv4PayloadIsV6UseFlowLabel_f, &hash_ctl, value);
            SetIpeHashCtl0(V, bulk12And13Ipv6UseFlowLabel0_f, &hash_ctl, value);
            SetIpeHashCtl0(V, bulk12And13Ipv6UseFlowLabel1_f, &hash_ctl, value);
            SetIpeHashCtl0(V, bulk12And13Ipv6UseFlowLabel2_f, &hash_ctl, value);
            SetIpeHashCtl0(V, bulk12And13Ipv6UseFlowLabel3_f, &hash_ctl, value);
            SetIpeHashCtl0(V, bulk12And13Ipv6UseFlowLabel4_f, &hash_ctl, value);
            SetIpeHashCtl0(V, bulk12And13Ipv6UseFlowLabel5_f, &hash_ctl, value);
            SetIpeHashCtl0(V, ipv4VxlanInnerL3Bulk12Andl3UseVni_f, &hash_ctl, value);
            SetIpeHashCtl0(V, ipv6VxlanInnerL3Bulk12Andl3UseVni_f, &hash_ctl, value);
            SetIpeHashCtl0(V, v4VxlanOuterL3HashUdfFieldUseVni_f, &hash_ctl, value);
            SetIpeHashCtl0(V, v6VxlanOuterL3HashUdfFieldUseVni_f, &hash_ctl, value);
            SetIpeHashCtl0(V, ipv4NvgreInnerL3Bulk12And13UseVsiId_f, &hash_ctl, value);
            SetIpeHashCtl0(V, ipv6NvgreInnerL3Bulk12And13UseVsiId_f, &hash_ctl, value);
            break;

        default:
            return CTC_E_INVALID_PARAM;
    }
    if(MCHIP_CAP(SYS_CAP_LB_HASH_SELECT_NUM) != SYS_USW_LB_HASH_CTL_NUM ||
        !DRV_FROM_TMM(lchip) || p_hash_cfg->hash_control != CTC_LB_HASH_CONTROL_HASH_TYPE_B)
    {
        cmd = DRV_IOW(IpeHashCtl0_t + index, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hash_ctl));
    }
    if(SYS_LB_HASH_IS_COMPATIBLE_MODE && p_hash_cfg->hash_control != CTC_LB_HASH_CONTROL_HASH_TYPE_A)
    {
        if(p_hash_cfg->hash_control != CTC_LB_HASH_CONTROL_HASH_TYPE_B)
        {
            uint32 field_id = (p_hash_cfg->sel_id / 2 == 0) ? IpeHashCtl1_hashPolySelectA_f : IpeHashCtl5_hashPolySelectA_f;
            cmd = DRV_IOR(IpeHashCtl0_t + index + 1, field_id);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
            SetIpeHashCtl0(V, hashPolySelectA_f, &hash_ctl, value);
        }
        cmd = DRV_IOW(IpeHashCtl0_t + index + 1, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hash_ctl));
    }
    return CTC_E_NONE;
}

int32
_sys_tsingma_hash_config_get_hash_control(uint8 lchip, ctc_lb_hash_config_t* p_hash_cfg)
{
    IpeHashCtl0_m hash_ctl;
    uint32 cmd = 0;
    uint32 value = 0;
    uint8  step  = 0;
    uint8 index = SYS_LB_HASH_IS_COMPATIBLE_MODE ? p_hash_cfg->sel_id * 2 : p_hash_cfg->sel_id;
    sal_memset(&hash_ctl, 0, sizeof(hash_ctl));

    index = (SYS_LB_HASH_IS_COMPATIBLE_MODE && p_hash_cfg->hash_control == CTC_LB_HASH_CONTROL_HASH_TYPE_B)? index + 1 : index;
    cmd = DRV_IOR(IpeHashCtl0_t + index, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hash_ctl));

    switch (p_hash_cfg->hash_control)
    {
        case CTC_LB_HASH_CONTROL_L2_ONLY:
            value = GetIpeHashCtl0(V, disableIpv4Hash_f, &hash_ctl);
            value &= GetIpeHashCtl0(V, disableIpv6Hash_f, &hash_ctl);
            value &= GetIpeHashCtl0(V, disableMplsHash_f, &hash_ctl);
            value &= GetIpeHashCtl0(V, disableFcoeHash_f, &hash_ctl);
            value &= GetIpeHashCtl0(V, disableTrillHash_f, &hash_ctl);
            p_hash_cfg->value = value;
            break;

        case CTC_LB_HASH_CONTROL_DISABLE_IPV4:
            p_hash_cfg->value = GetIpeHashCtl0(V, disableIpv4Hash_f, &hash_ctl);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_IPV6:
            p_hash_cfg->value = GetIpeHashCtl0(V, disableIpv6Hash_f, &hash_ctl);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_MPLS:
            p_hash_cfg->value = GetIpeHashCtl0(V, disableMplsHash_f, &hash_ctl);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_FCOE:
            p_hash_cfg->value = GetIpeHashCtl0(V, disableFcoeHash_f, &hash_ctl);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TRILL:
            p_hash_cfg->value = GetIpeHashCtl0(V, disableTrillHash_f, &hash_ctl);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TUNNEL_IPV4_IN4:
            value = GetIpeHashCtl0(V, ipv4EnableInnerHashTunnelBitmap_f, &hash_ctl);
            p_hash_cfg->value = !CTC_IS_BIT_SET(value, 2);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TUNNEL_IPV6_IN4:
            value = GetIpeHashCtl0(V, ipv4EnableInnerHashTunnelBitmap_f, &hash_ctl);
            p_hash_cfg->value = !CTC_IS_BIT_SET(value, 1);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TUNNEL_GRE_IN4:
            value = GetIpeHashCtl0(V, ipv4EnableInnerHashTunnelBitmap_f, &hash_ctl);
            p_hash_cfg->value = !CTC_IS_BIT_SET(value, 3);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TUNNEL_NVGRE_IN4:
            value = GetIpeHashCtl0(V, ipv4EnableInnerHashTunnelBitmap_f, &hash_ctl);
            p_hash_cfg->value = !CTC_IS_BIT_SET(value, 4);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TUNNEL_VXLAN_IN4:
            value = GetIpeHashCtl0(V, ipv4EnableInnerHashTunnelBitmap_f, &hash_ctl);
            p_hash_cfg->value = !CTC_IS_BIT_SET(value, 5);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TUNNEL_IPV4_IN6:
            value = GetIpeHashCtl0(V, ipv6EnableInnerHashTunnelBitmap_f, &hash_ctl);
            p_hash_cfg->value = !CTC_IS_BIT_SET(value, 2);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TUNNEL_IPV6_IN6:
            value = GetIpeHashCtl0(V, ipv6EnableInnerHashTunnelBitmap_f, &hash_ctl);
            p_hash_cfg->value = !CTC_IS_BIT_SET(value, 1);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TUNNEL_GRE_IN6:
            value = GetIpeHashCtl0(V, ipv6EnableInnerHashTunnelBitmap_f, &hash_ctl);
            p_hash_cfg->value = !CTC_IS_BIT_SET(value, 3);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TUNNEL_NVGRE_IN6:
            value = GetIpeHashCtl0(V, ipv6EnableInnerHashTunnelBitmap_f, &hash_ctl);
            p_hash_cfg->value = !CTC_IS_BIT_SET(value, 4);
            break;
        case CTC_LB_HASH_CONTROL_DISABLE_TUNNEL_VXLAN_IN6:
            value = GetIpeHashCtl0(V, ipv6EnableInnerHashTunnelBitmap_f, &hash_ctl);
            p_hash_cfg->value = !CTC_IS_BIT_SET(value, 5);
            break;
        case CTC_LB_HASH_CONTROL_MPLS_EXCLUDE_RSV:
            p_hash_cfg->value = GetIpeHashCtl0(V, mplsHashSkipReservedLabel_f, &hash_ctl);
            break;
        case CTC_LB_HASH_CONTROL_IPV6_ADDR_COLLAPSE:
            p_hash_cfg->value = GetIpeHashCtl0(V, ipv6AddrCompressMode_f, &hash_ctl);
            break;
        case CTC_LB_HASH_CONTROL_IPV6_USE_FLOW_LABEL:
            p_hash_cfg->value = GetIpeHashCtl0(V, ipv4PayloadIsV6UseFlowLabel_f, &hash_ctl);
            break;
        case CTC_LB_HASH_CONTROL_NVGRE_AWARE:
            p_hash_cfg->value = GetIpeHashCtl0(V, awaredNvgre_f, &hash_ctl);
            break;
        case CTC_LB_HASH_CONTROL_FCOE_SYMMETRIC_EN:
            p_hash_cfg->value = GetIpeHashCtl0(V, fcoeSymmetricHashEn_f, &hash_ctl);
            break;
        case CTC_LB_HASH_CONTROL_UDF_SELECT_MODE:
            value = GetIpeHashCtl0(V, udfDataSel_f, &hash_ctl) ;
            p_hash_cfg->value = (value == 4) ? CTC_LB_HASH_UDF_SEL_MODE8 : value;
            if(!DRV_FROM_TMM(lchip))
            {
                switch (value)
                {
                    case 7:
                        p_hash_cfg->value = CTC_LB_HASH_UDF_SEL_MODE0;
                        break;
                    case 6:
                        p_hash_cfg->value = CTC_LB_HASH_UDF_SEL_MODE1;
                        break;
                    case 5:
                        p_hash_cfg->value = CTC_LB_HASH_UDF_SEL_MODE2;
                        break;
                    case 0:
                        p_hash_cfg->value = CTC_LB_HASH_UDF_SEL_MODE3;
                        break;
                    case 3:
                        p_hash_cfg->value = CTC_LB_HASH_UDF_SEL_MODE4;
                        break;
                    case 2:
                        p_hash_cfg->value = CTC_LB_HASH_UDF_SEL_MODE5;
                        break;
                    case 1:
                        p_hash_cfg->value = CTC_LB_HASH_UDF_SEL_MODE6;
                        if ((SYS_GET_CHIP_VERSION != SYS_CHIP_SUB_VERSION_A) && DRV_IS_TSINGMA(lchip))
                        {
                            cmd = DRV_IOR(IpeLkupMgrReserved_t, IpeLkupMgrReserved_reserved_f);
                            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
                            p_hash_cfg->value = CTC_IS_BIT_SET(value, 2) ? CTC_LB_HASH_UDF_SEL_MODE8 : CTC_LB_HASH_UDF_SEL_MODE6;
                        }
                        break;
                    case 4:
                        p_hash_cfg->value = CTC_LB_HASH_UDF_SEL_MODE7;
                        break;
                    default:
                        return CTC_E_INVALID_PARAM;
                }
            }
            break;
        case CTC_LB_HASH_CONTROL_USE_MAPPED_VLAN:
            p_hash_cfg->value = GetIpeHashCtl0(V, vidDataSel_f, &hash_ctl);
            break;
        case CTC_LB_HASH_CONTROL_IPV4_SYMMETRIC_EN:
            p_hash_cfg->value = GetIpeHashCtl0(V, outerIpv4SymmetricHashEn_f, &hash_ctl);
            break;
        case CTC_LB_HASH_CONTROL_IPV6_SYMMETRIC_EN:
            p_hash_cfg->value = GetIpeHashCtl0(V, outerIpv6SymmetricHashEn_f, &hash_ctl);
            break;
        case CTC_LB_HASH_CONTROL_L2VPN_USE_INNER_L2:
            p_hash_cfg->value = GetIpeHashCtl0(V, mplsL2VpnDecapsUseInnerL2Hash_f, &hash_ctl);
            break;
        case CTC_LB_HASH_CONTROL_VPWS_USE_INNER:
            p_hash_cfg->value = GetIpeHashCtl0(V, vpwsDecapsHashMode_f, &hash_ctl);
            break;
        case CTC_LB_HASH_CONTROL_TRILL_DECAP_USE_INNER_L2:
            p_hash_cfg->value = GetIpeHashCtl0(V, trillTerminateNodeHashMode_f, &hash_ctl)?0:1;
            break;
        case CTC_LB_HASH_CONTROL_TRILL_TRANSMIT_MODE:
            p_hash_cfg->value = GetIpeHashCtl0(V, trillTransitNodeHashMode_f, &hash_ctl);
            break;
        case CTC_LB_HASH_CONTROL_MPLS_ENTROPY_EN:
            p_hash_cfg->value = GetIpeHashCtl0(V, mplsL2VpnDecapsVpwsUseGlobalInnerHdrHashA_f, &hash_ctl);
            break;
        case CTC_LB_HASH_CONTROL_MPLS_LABEL2_EN:
            value = GetIpeHashCtl0(V, hashTemplate3Bulk13IsMplsLabel_f, &hash_ctl);
            p_hash_cfg->value = value ? 1 : 0;
            break;
        case CTC_LB_HASH_CONTROL_VXLAN_USE_INNER_L2:
            p_hash_cfg->value =  GetIpeHashCtl0(V, vxlanInnerL2HashEn_f, &hash_ctl);
            break;
        case CTC_LB_HASH_CONTROL_NVGRE_USE_INNER_L2:
            p_hash_cfg->value = GetIpeHashCtl0(V, nvGreInnerL2HashEn_f, &hash_ctl);
            break;
        case CTC_LB_HASH_CONTROL_FLEX_TNL_USE_INNER_L2:
            p_hash_cfg->value = GetIpeHashCtl0(V, forceInnerL2HashEn_f, &hash_ctl);
            break;
        case CTC_LB_HASH_CONTROL_HASH_SEED:
            p_hash_cfg->value = GetIpeHashCtl0(V, hashSeed_f, &hash_ctl);
            break;

        case CTC_LB_HASH_CONTROL_HASH_TYPE_A:
        case CTC_LB_HASH_CONTROL_HASH_TYPE_B:
            {
                value = (SYS_LB_HASH_IS_COMPATIBLE_MODE || p_hash_cfg->hash_control == CTC_LB_HASH_CONTROL_HASH_TYPE_A)?
                GetIpeHashCtl0(V, hashPolySelectA_f, &hash_ctl):
                GetIpeHashCtl0(V, hashPolySelectB_f, &hash_ctl);
                switch(value)
                {
                case SYS_LB_HASHPOLY_CRC8_POLY1:
                    p_hash_cfg->value = CTC_LB_HASH_TYPE_CRC8_POLY1;
                    break;
                case SYS_LB_HASHPOLY_CRC8_POLY2:
                    p_hash_cfg->value = CTC_LB_HASH_TYPE_CRC8_POLY2;
                    break;
                case SYS_LB_HASHPOLY_XOR8:
                    p_hash_cfg->value = CTC_LB_HASH_TYPE_XOR8;
                    break;
                case SYS_LB_HASHPOLY_CRC10_POLY1:
                    p_hash_cfg->value = CTC_LB_HASH_TYPE_CRC10_POLY1;
                    break;
                case SYS_LB_HASHPOLY_CRC10_POLY2:
                    p_hash_cfg->value = CTC_LB_HASH_TYPE_CRC10_POLY2;
                    break;
                case SYS_LB_HASHPOLY_XOR16:
                    p_hash_cfg->value = CTC_LB_HASH_TYPE_XOR16;
                    break;
                case SYS_LB_HASHPOLY_CRC16_POLY1:
                    p_hash_cfg->value = DRV_FROM_TMM(lchip) ? CTC_LB_HASH_TYPE_CRC8_POLY1 : CTC_LB_HASH_TYPE_CRC16_POLY1;
                    break;
                case SYS_LB_HASHPOLY_CRC16_POLY2:
                    p_hash_cfg->value = CTC_LB_HASH_TYPE_CRC16_POLY2;
                    break;
                case SYS_LB_HASHPOLY_CRC16_POLY3:
                    p_hash_cfg->value = CTC_LB_HASH_TYPE_CRC16_POLY3;
                    break;
                case SYS_LB_HASHPOLY_CRC16_POLY4:
                    p_hash_cfg->value = CTC_LB_HASH_TYPE_CRC16_POLY4;
                    break;
                case SYS_LB_HASHPOLY_CRC16_POLY5:
                    p_hash_cfg->value = CTC_LB_HASH_TYPE_CRC16_POLY5;
                    break;
                case SYS_LB_HASHPOLY_CRC16_POLY6:
                    p_hash_cfg->value = CTC_LB_HASH_TYPE_CRC16_POLY6;
                    break;
                case SYS_LB_HASHPOLY_CRC32_POLY1:
                    p_hash_cfg->value = CTC_LB_HASH_TYPE_CRC32_POLY1;
                    break;
                case SYS_LB_HASHPOLY_CRC32_POLY2:
                    p_hash_cfg->value = CTC_LB_HASH_TYPE_CRC32_POLY2;
                    break;
                case SYS_LB_HASHPOLY_NO_CALC:
                    p_hash_cfg->value = SYS_LB_HASHPOLY_NO_CALC;
                    break;
                default:
                    return CTC_E_INVALID_PARAM;
                }
            }
            break;
            /*corresponding byte mask if set, mean that the byte don't uesed to compute hash value*/
        case CTC_LB_HASH_CONTROL_HASH_TYPE_UDF_DATA_BYTE_MASK:
            if (DRV_FROM_TMM(lchip))
            {
                uint8 udf_mask[CTC_LB_HASH_UDF_BYTE_NUM] = {0};
                uint8 index = 0;
                cmd = DRV_IOR(IpeLkpManagerHashBulkBitmapCtl_t, IpeLkpManagerHashBulkBitmapCtl_udfHashBitMask_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, p_hash_cfg->sel_id, cmd, udf_mask));
                for (index = 0; index < CTC_LB_HASH_UDF_BYTE_NUM; index++)
                {
                    if(0 == udf_mask[index])
                    {
                        CTC_BIT_SET(value,index);
                    }
                }
            }
            else
            {
                step =  IpeSclFlowHashBulkBitmapCtl_array_1_flexHashUdfByteMask_f - IpeSclFlowHashBulkBitmapCtl_array_0_flexHashUdfByteMask_f;
                cmd = DRV_IOR(IpeSclFlowHashBulkBitmapCtl_t, IpeSclFlowHashBulkBitmapCtl_array_0_flexHashUdfByteMask_f + step * p_hash_cfg->sel_id);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
            }
            p_hash_cfg->value = value;

            break;
            /*corresponding bit mask if set, mean that the byte will uesed to compute hash value*/
        case CTC_LB_HASH_CONTROL_HASH_TYPE_UDF_DATA_BIT_MASK:
            cmd = DRV_IOR(IpeLkpManagerHashBulkBitmapCtl_t, IpeLkpManagerHashBulkBitmapCtl_udfHashBitMask_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, p_hash_cfg->sel_id, cmd, p_hash_cfg->udf_mask));
            break;
        case CTC_LB_HASH_CONTROL_HASH_SEED_USE_UDF:
            p_hash_cfg->value = GetIpeHashCtl0(V, enableUdfMode_f, &hash_ctl);
            break;
        case SYS_LB_HASH_CONTROL_L2VPN_USE_OUTER_L3:
            p_hash_cfg->value = GetIpeHashCtl0(V, forceL2VpnMplsHashEn_f, &hash_ctl);
            break;
        case SYS_LB_HASH_CONTROL_L3VPN_USE_OUTER_L3:
            p_hash_cfg->value = GetIpeHashCtl0(V, forceL3VpnMplsHashEn_f, &hash_ctl);
            break;
        case SYS_LB_HASH_CONTROL_MPLS_TRANSMIT_MODE:
            p_hash_cfg->value = (GetIpeHashCtl0(V, mplsTransitUseTemplateMode_f, &hash_ctl))? 2 :
                                (GetIpeHashCtl0(V, hashTemplate3Bulk13IsMplsLabel_f, &hash_ctl))? 1 : 0;
            break;
        case SYS_LB_HASH_CONTROL_GRE_INNER_L2_USE_VSID:
            p_hash_cfg->value = GetIpeHashCtl0(V, nvgreInnerL2HashUseVsid_f, &hash_ctl);
            break;

        case SYS_LB_HASH_CONTROL_VXLAN_INNER_L2_USE_VNI:
            p_hash_cfg->value = GetIpeHashCtl0(V, vxlanInnerL2HashUseVni_f, &hash_ctl);
            break;

        case SYS_LB_HASH_CONTROL_UDF_BULK_EN:
            p_hash_cfg->value = !GetIpeHashCtl0(V, ipv4PayloadIsV6UseFlowLabel_f, &hash_ctl);
            break;
            
        default:
            return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32
sys_tsingma_hash_set_hash_control(uint8 lchip, void* p_hash_ctl)
{
    CTC_PTR_VALID_CHECK(p_hash_ctl);
    return _sys_tsingma_hash_config_set_hash_control(lchip, (ctc_lb_hash_config_t*)p_hash_ctl);
}

int32
sys_tsingma_hash_get_hash_control(uint8 lchip, void* p_hash_ctl)
{
    CTC_PTR_VALID_CHECK(p_hash_ctl);
    return _sys_tsingma_hash_config_get_hash_control(lchip, (ctc_lb_hash_config_t*)p_hash_ctl);
}

int32
sys_tsingma_hash_set_config(uint8 lchip, void* p_hash)
{
    ctc_lb_hash_config_t* p_hash_cfg = 0;
    p_hash_cfg = (ctc_lb_hash_config_t*) p_hash;
    CTC_PTR_VALID_CHECK(p_hash_cfg);

    /*CTC_MAX_VALUE_CHECK(p_hash_cfg->cfg_type,1);
    */
    CTC_MAX_VALUE_CHECK(p_hash_cfg->hash_select, CTC_LB_HASH_SELECT_MAX - 1);
    CTC_MAX_VALUE_CHECK(p_hash_cfg->hash_control, CTC_LB_HASH_CONTROL_MAX - 1);
    CTC_MAX_VALUE_CHECK(p_hash_cfg->value, 0xFFFFFFFF);

    if (p_hash_cfg->cfg_type == CTC_LB_HASH_CFG_HASH_SELECT)
    {
        if (p_hash_cfg->hash_select == CTC_LB_HASH_SELECT_UDF)
        {
            uint8 sel_id = 0;
            uint8 udf_profile_id = 0;
            SYS_LB_HASH_DECODE_SEL_ID(p_hash_cfg->sel_id, sel_id, udf_profile_id);
            CTC_MAX_VALUE_CHECK(sel_id, MCHIP_CAP(SYS_CAP_LB_HASH_SELECT_NUM) - 1);
            CTC_VALUE_RANGE_CHECK(udf_profile_id, 1, SYS_LB_HASH_SCL_PROFILE_NUM-1);
            CTC_ERROR_RETURN(_sys_tsingma_hash_config_set_udf_select(lchip, p_hash_cfg));
        }
        else
        {
            CTC_MAX_VALUE_CHECK(p_hash_cfg->sel_id, MCHIP_CAP(SYS_CAP_LB_HASH_SELECT_NUM) - 1);
            CTC_ERROR_RETURN(_sys_tsingma_hash_config_set_hash_select(lchip, p_hash_cfg));
        }
    }
    else if (p_hash_cfg->cfg_type == CTC_LB_HASH_CFG_HASH_CONTROL)
    {
        if (p_hash_cfg->hash_control != CTC_LB_HASH_CONTROL_HASH_TYPE_UDF_DATA_BYTE_MASK
            && p_hash_cfg->hash_control != CTC_LB_HASH_CONTROL_HASH_TYPE_UDF_DATA_BIT_MASK)
        {
            CTC_MAX_VALUE_CHECK(p_hash_cfg->sel_id, MCHIP_CAP(SYS_CAP_LB_HASH_SELECT_NUM) - 1);
        }
        else
        {
            CTC_MAX_VALUE_CHECK(p_hash_cfg->sel_id, SYS_LB_HASH_SCL_PROFILE_NUM-1);
            CTC_MIN_VALUE_CHECK(p_hash_cfg->sel_id, 1);
        }
        CTC_ERROR_RETURN(_sys_tsingma_hash_config_set_hash_control(lchip, p_hash_cfg));
    }
    else
    {
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32
sys_tsingma_hash_get_config(uint8 lchip, void* p_hash)
{
    ctc_lb_hash_config_t* p_hash_cfg = 0;
    p_hash_cfg = (ctc_lb_hash_config_t*) p_hash;
    CTC_PTR_VALID_CHECK(p_hash_cfg);

    if (p_hash_cfg->cfg_type == CTC_LB_HASH_CFG_HASH_SELECT)
    {
        if (p_hash_cfg->hash_select == CTC_LB_HASH_SELECT_UDF)
        {
            uint8 sel_id = 0;
            uint8 udf_profile_id = 0;
            SYS_LB_HASH_DECODE_SEL_ID(p_hash_cfg->sel_id, sel_id, udf_profile_id);
            CTC_MAX_VALUE_CHECK(sel_id, MCHIP_CAP(SYS_CAP_LB_HASH_SELECT_NUM) - 1);
            CTC_VALUE_RANGE_CHECK(udf_profile_id, 1, SYS_LB_HASH_SCL_PROFILE_NUM-1);
            CTC_ERROR_RETURN(_sys_tsingma_hash_config_get_udf_select(lchip, p_hash_cfg));
        }
        else
        {
            CTC_MAX_VALUE_CHECK(p_hash_cfg->sel_id, MCHIP_CAP(SYS_CAP_LB_HASH_SELECT_NUM) - 1);
            CTC_ERROR_RETURN(_sys_tsingma_hash_config_get_hash_select(lchip, p_hash_cfg));
        }
    }
    else if (p_hash_cfg->cfg_type == CTC_LB_HASH_CFG_HASH_CONTROL)
    {
        if (p_hash_cfg->hash_control != CTC_LB_HASH_CONTROL_HASH_TYPE_UDF_DATA_BYTE_MASK
            && p_hash_cfg->hash_control != CTC_LB_HASH_CONTROL_HASH_TYPE_UDF_DATA_BIT_MASK)
        {
            CTC_MAX_VALUE_CHECK(p_hash_cfg->sel_id, MCHIP_CAP(SYS_CAP_LB_HASH_SELECT_NUM) - 1);
        }
        else
        {
            CTC_MAX_VALUE_CHECK(p_hash_cfg->sel_id, SYS_LB_HASH_SCL_PROFILE_NUM-1);
        }
        CTC_ERROR_RETURN(_sys_tsingma_hash_config_get_hash_control(lchip, p_hash_cfg));
    }
    else
    {
        return CTC_E_INVALID_PARAM;
    }


    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_hash_set_lag_offset(uint8 lchip, ctc_lb_hash_offset_t* p_hash_offset)
{
    uint8 offset = 0;
    uint8 select = 0;
    uint32 cmd0 = 0;
    uint8 offset_valid = (CTC_LB_HASH_OFFSET_DISABLE == p_hash_offset->offset)? 0 : 1;
    DsPortBasedHashProfile1_m DsPortBasedHashProfile1;
    DsPortBasedHashProfile0_m DsPortBasedHashProfile0;

    sal_memset(&DsPortBasedHashProfile1, 0, sizeof(DsPortBasedHashProfile1));

    cmd0 = DRV_IOR(DsPortBasedHashProfile1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, (p_hash_offset->profile_id), cmd0, &DsPortBasedHashProfile1));
    cmd0 = DRV_IOR(DsPortBasedHashProfile0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, (p_hash_offset->profile_id), cmd0, &DsPortBasedHashProfile0));

    select = (p_hash_offset->offset) / 16;
    offset = (p_hash_offset->offset) % 16;
    select |= p_hash_offset->use_packet_head_hash ? 8 : 0;

    switch (p_hash_offset->hash_mode)
    {
        case CTC_LB_HASH_MODE_STATIC:
            SetDsPortBasedHashProfile1(V, gLag_0_slbValid_f, &DsPortBasedHashProfile1, offset_valid);
            SetDsPortBasedHashProfile1(V, gLag_0_hashSelectForSlb_f, &DsPortBasedHashProfile1, select);
            SetDsPortBasedHashProfile1(V, gLag_0_hashOffsetForSlb_f, &DsPortBasedHashProfile1, offset);

            SetDsPortBasedHashProfile0(V, gLbid_ucValid_f, &DsPortBasedHashProfile0, offset_valid);
            SetDsPortBasedHashProfile0(V, gLbid_hashSelectForUc_f, &DsPortBasedHashProfile0, select);
            SetDsPortBasedHashProfile0(V, gLbid_hashOffsetForUc_f, &DsPortBasedHashProfile0, offset);
            break;

        case CTC_LB_HASH_MODE_DLB_FLOW_SET:
            SetDsPortBasedHashProfile1(V, gLag_0_dlbValid_f, &DsPortBasedHashProfile1, offset_valid);
            SetDsPortBasedHashProfile1(V, gLag_0_hashSelectForDlb_f, &DsPortBasedHashProfile1, select);
            SetDsPortBasedHashProfile1(V, gLag_0_hashOffsetForDlb_f, &DsPortBasedHashProfile1, offset);
            break;

        case CTC_LB_HASH_MODE_LSH:
            SetDsPortBasedHashProfile1(V, portLagLshValid_f, &DsPortBasedHashProfile1, offset_valid);
            SetDsPortBasedHashProfile1(V, hashSelectForPortLagLsh_f, &DsPortBasedHashProfile1, select);
            SetDsPortBasedHashProfile1(V, hashOffsetForPortLagLsh_f, &DsPortBasedHashProfile1, offset);
            break;

        default:
            return CTC_E_INVALID_PARAM;
    }

    cmd0 = DRV_IOW(DsPortBasedHashProfile1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, (p_hash_offset->profile_id), cmd0, &DsPortBasedHashProfile1));
    cmd0 = DRV_IOW(DsPortBasedHashProfile0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, (p_hash_offset->profile_id), cmd0, &DsPortBasedHashProfile0));

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_hash_get_lag_offset(uint8 lchip, ctc_lb_hash_offset_t* p_hash_offset)
{
    uint8 offset = 0;
    uint8 select = 0;
    uint32 cmd0 = 0;
    uint8 fld_offset = 0;
    uint8 offset_valid = 0;
    DsPortBasedHashProfile1_m DsPortBasedHashProfile1;

    sal_memset(&DsPortBasedHashProfile1, 0, sizeof(DsPortBasedHashProfile1));


    cmd0 = DRV_IOR(DsPortBasedHashProfile1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, (p_hash_offset->profile_id), cmd0, &DsPortBasedHashProfile1));


    if (p_hash_offset->hash_module == CTC_LB_HASH_MODULE_STACKING)
    {
        fld_offset = (DsPortBasedHashProfile1_gLag_1_slbValid_f - DsPortBasedHashProfile1_gLag_0_slbValid_f);
    }
    else if (p_hash_offset->hash_module == CTC_LB_HASH_MODULE_LINKAGG)
    {
        fld_offset = 0;
    }

    switch (p_hash_offset->hash_mode)
    {
        case CTC_LB_HASH_MODE_STATIC:
            select = GetDsPortBasedHashProfile1(V, gLag_0_hashSelectForSlb_f + fld_offset, &DsPortBasedHashProfile1);
            offset = GetDsPortBasedHashProfile1(V, gLag_0_hashOffsetForSlb_f + fld_offset, &DsPortBasedHashProfile1);
            offset_valid = GetDsPortBasedHashProfile1(V, gLag_0_slbValid_f + fld_offset, &DsPortBasedHashProfile1);
            break;

        case CTC_LB_HASH_MODE_DLB_FLOW_SET:
            select = GetDsPortBasedHashProfile1(V, gLag_0_hashSelectForDlb_f + fld_offset, &DsPortBasedHashProfile1);
            offset = GetDsPortBasedHashProfile1(V, gLag_0_hashOffsetForDlb_f + fld_offset, &DsPortBasedHashProfile1);
            offset_valid = GetDsPortBasedHashProfile1(V, gLag_0_dlbValid_f + fld_offset, &DsPortBasedHashProfile1);
            break;

        case CTC_LB_HASH_MODE_LSH:
            select = GetDsPortBasedHashProfile1(V, hashSelectForPortLagLsh_f, &DsPortBasedHashProfile1);
            offset = GetDsPortBasedHashProfile1(V, hashOffsetForPortLagLsh_f, &DsPortBasedHashProfile1);
            offset_valid = GetDsPortBasedHashProfile1(V, portLagLshValid_f, &DsPortBasedHashProfile1);
            break;

        default:
            return CTC_E_INVALID_PARAM;
    }

    if (offset_valid)
    {
        p_hash_offset->use_packet_head_hash = select>>3;
        p_hash_offset->offset = (select&0x7)*16 + offset;
    }
    else
    {
        p_hash_offset->offset = CTC_LB_HASH_OFFSET_DISABLE;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_hash_set_ecmp_offset(uint8 lchip, ctc_lb_hash_offset_t* p_hash_offset)
{
    uint8 offset = 0;
    uint8 select = 0;
    uint8 hecmp_select = 0;
    uint32 cmd0 = 0;
    uint8 use_entropy = 0;
    uint8 offset_valid = (CTC_LB_HASH_OFFSET_DISABLE == p_hash_offset->offset)? 0: 1;
    uint8 step1 = 0;
    uint8 step2 = 0;
    uint8 step3 = 0;
    uint8 step4 = 0;
    uint8 dlb_valid = 0;
    uint8 hash_mode = 0;
    DsPortBasedHashProfile0_m DsPortBasedHashProfile0;
    IpeEcmpCtl_m IpeEcmpCtl;
    IpeFwdCtl_m IpeFwdCtl;
    if (p_hash_offset->profile_id == CTC_LB_HASH_ECMP_GLOBAL_PROFILE)
    {
        sal_memset(&IpeEcmpCtl, 0, sizeof(IpeEcmpCtl));
        sal_memset(&IpeFwdCtl, 0, sizeof(IpeFwdCtl));
        cmd0 = DRV_IOR(IpeEcmpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd0, &IpeEcmpCtl));
        cmd0 = DRV_IOR(IpeFwdCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd0, &IpeFwdCtl));
    }
    else
    {
        sal_memset(&DsPortBasedHashProfile0, 0, sizeof(DsPortBasedHashProfile0));
        cmd0 = DRV_IOR(DsPortBasedHashProfile0_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_hash_offset->profile_id, cmd0, &DsPortBasedHashProfile0));
    }

    select = (p_hash_offset->offset) / 16;
    offset = (p_hash_offset->offset) % 16;
    select |= p_hash_offset->use_packet_head_hash ? 8 : 0;

    use_entropy = p_hash_offset->use_entropy_hash?1:0;


    switch (p_hash_offset->hash_mode)
    {
    case CTC_LB_HASH_MODE_NONE:
        for (hash_mode = CTC_LB_HASH_MODE_STATIC; hash_mode <= CTC_LB_HASH_MODE_DLB_MEMBER; hash_mode++)
        {
            p_hash_offset->hash_mode = hash_mode;
            CTC_ERROR_RETURN(_sys_tsingma_hash_set_ecmp_offset(lchip, p_hash_offset));
        }
        return CTC_E_NONE;
    case CTC_LB_HASH_MODE_STATIC:
        if(p_hash_offset->fwd_type != CTC_LB_HASH_FWD_NONE && p_hash_offset->fwd_type != CTC_LB_HASH_FWD_VXLAN && 
           p_hash_offset->fwd_type != CTC_LB_HASH_FWD_NVGRE && p_hash_offset->fwd_type != CTC_LB_HASH_FWD_MPLS && 
           p_hash_offset->fwd_type != CTC_LB_HASH_FWD_IP)
        {
            return CTC_E_INVALID_PARAM;
        }
        if (p_hash_offset->fwd_type == CTC_LB_HASH_FWD_VXLAN || p_hash_offset->fwd_type == CTC_LB_HASH_FWD_NONE)
        {
            if (p_hash_offset->profile_id == CTC_LB_HASH_ECMP_GLOBAL_PROFILE)
            {
                step1 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_vxlanEcmpUseEntropy_f - IpeEcmpCtl_gLevel1_vxlanEcmpUseEntropy_f : 0;
                step2 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_hashOffsetForVxlanEcmp_f - IpeEcmpCtl_gLevel1_hashOffsetForVxlanEcmp_f : 0;
                step3 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_hashSelectForVxlanEcmp_f - IpeEcmpCtl_gLevel1_hashSelectForVxlanEcmp_f : 0;
                /*entropy */
                SetIpeEcmpCtl(V, vxlanEcmpUseEntropy_f - step1, &IpeEcmpCtl, use_entropy);

                SetIpeEcmpCtl(V, hashOffsetForVxlanEcmp_f - step2, &IpeEcmpCtl, offset);
                SetIpeEcmpCtl(V, hashSelectForVxlanEcmp_f - step3, &IpeEcmpCtl, select);
            }
            else
            {
                step1 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_vxlanEcmpUseEntropy_f - DsPortBasedHashProfile0_gEcmpL1_vxlanEcmpUseEntropy_f : 0;
                step2 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_slbVxlanValid_f - DsPortBasedHashProfile0_gEcmpL1_slbVxlanValid_f : 0;
                step3 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_hashOffsetForSlbVxlan_f - DsPortBasedHashProfile0_gEcmpL1_hashOffsetForSlbVxlan_f : 0;
                step4 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_hashSelectForSlbVxlan_f - DsPortBasedHashProfile0_gEcmpL1_hashSelectForSlbVxlan_f : 0;
                /*entropy */
                SetDsPortBasedHashProfile0(V, gEcmp_vxlanEcmpUseEntropy_f - step1, &DsPortBasedHashProfile0, use_entropy);

                SetDsPortBasedHashProfile0(V, gEcmp_slbVxlanValid_f - step2, &DsPortBasedHashProfile0, offset_valid);
                SetDsPortBasedHashProfile0(V, gEcmp_hashOffsetForSlbVxlan_f - step3, &DsPortBasedHashProfile0, offset);
                SetDsPortBasedHashProfile0(V, gEcmp_hashSelectForSlbVxlan_f - step4, &DsPortBasedHashProfile0, select);
            }
        }
        if (p_hash_offset->fwd_type == CTC_LB_HASH_FWD_NVGRE || p_hash_offset->fwd_type == CTC_LB_HASH_FWD_NONE)
        {
            if (p_hash_offset->profile_id == CTC_LB_HASH_ECMP_GLOBAL_PROFILE)
            {
                step1 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_nvgreEcmpUseEntropy_f - IpeEcmpCtl_gLevel1_nvgreEcmpUseEntropy_f : 0;
                step2 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_hashOffsetForNvgreEcmp_f - IpeEcmpCtl_gLevel1_hashOffsetForNvgreEcmp_f : 0;
                step3 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_hashSelectForNvgreEcmp_f - IpeEcmpCtl_gLevel1_hashSelectForNvgreEcmp_f : 0;
                /*entropy */
                SetIpeEcmpCtl(V, nvgreEcmpUseEntropy_f - step1, &IpeEcmpCtl, use_entropy);

                SetIpeEcmpCtl(V, hashOffsetForNvgreEcmp_f - step2, &IpeEcmpCtl, offset);
                SetIpeEcmpCtl(V, hashSelectForNvgreEcmp_f - step3, &IpeEcmpCtl, select);
            }
            else
            {
                step1 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_nvgreEcmpUseEntropy_f - DsPortBasedHashProfile0_gEcmpL1_nvgreEcmpUseEntropy_f : 0;
                step2 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_slbNvgreValid_f - DsPortBasedHashProfile0_gEcmpL1_slbNvgreValid_f : 0;
                step3 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_hashOffsetForSlbNvgre_f - DsPortBasedHashProfile0_gEcmpL1_hashOffsetForSlbNvgre_f : 0;
                step4 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_hashSelectForSlbNvgre_f - DsPortBasedHashProfile0_gEcmpL1_hashSelectForSlbNvgre_f : 0;
                /*entropy */
                SetDsPortBasedHashProfile0(V, gEcmp_nvgreEcmpUseEntropy_f - step1, &DsPortBasedHashProfile0, use_entropy);

                SetDsPortBasedHashProfile0(V, gEcmp_slbNvgreValid_f - step2, &DsPortBasedHashProfile0, offset_valid);
                SetDsPortBasedHashProfile0(V, gEcmp_hashOffsetForSlbNvgre_f - step3, &DsPortBasedHashProfile0, offset);
                SetDsPortBasedHashProfile0(V, gEcmp_hashSelectForSlbNvgre_f - step4, &DsPortBasedHashProfile0, select);
            }
        }
        if (p_hash_offset->fwd_type == CTC_LB_HASH_FWD_MPLS || p_hash_offset->fwd_type == CTC_LB_HASH_FWD_NONE)
        {
            if (p_hash_offset->profile_id == CTC_LB_HASH_ECMP_GLOBAL_PROFILE)
            {
                step1 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_mplsEcmpUseEntropy_f - IpeEcmpCtl_gLevel1_mplsEcmpUseEntropy_f : 0;
                step2 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_hashOffsetForMplsEcmp_f - IpeEcmpCtl_gLevel1_hashOffsetForMplsEcmp_f : 0;
                step3 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_hashSelectForMplsEcmp_f - IpeEcmpCtl_gLevel1_hashSelectForMplsEcmp_f : 0;
                /*entropy */
                SetIpeEcmpCtl(V, mplsEcmpUseEntropy_f - step1, &IpeEcmpCtl, use_entropy);

                SetIpeEcmpCtl(V, hashOffsetForMplsEcmp_f - step2, &IpeEcmpCtl, offset);
                SetIpeEcmpCtl(V, hashSelectForMplsEcmp_f - step3, &IpeEcmpCtl, select);
            }
            else
            {
                step1 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_mplsEcmpUseEntropy_f - DsPortBasedHashProfile0_gEcmpL1_mplsEcmpUseEntropy_f : 0;
                step2 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_slbMplsValid_f - DsPortBasedHashProfile0_gEcmpL1_slbMplsValid_f : 0;
                step3 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_hashOffsetForSlbMpls_f - DsPortBasedHashProfile0_gEcmpL1_hashOffsetForSlbMpls_f : 0;
                step4 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_hashSelectForSlbMpls_f - DsPortBasedHashProfile0_gEcmpL1_hashSelectForSlbMpls_f : 0;
                /*entropy */
                SetDsPortBasedHashProfile0(V, gEcmp_mplsEcmpUseEntropy_f - step1, &DsPortBasedHashProfile0, use_entropy);

                SetDsPortBasedHashProfile0(V, gEcmp_slbMplsValid_f - step2, &DsPortBasedHashProfile0, offset_valid);
                SetDsPortBasedHashProfile0(V, gEcmp_hashOffsetForSlbMpls_f - step3, &DsPortBasedHashProfile0, offset);
                SetDsPortBasedHashProfile0(V, gEcmp_hashSelectForSlbMpls_f - step4, &DsPortBasedHashProfile0, select);
            }
        }
        if (p_hash_offset->fwd_type == CTC_LB_HASH_FWD_IP || p_hash_offset->fwd_type == CTC_LB_HASH_FWD_NONE)
        {
            if (p_hash_offset->profile_id == CTC_LB_HASH_ECMP_GLOBAL_PROFILE)
            {
                step1 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_l3PktEcmpUseEntropy_f - IpeEcmpCtl_gLevel1_l3PktEcmpUseEntropy_f : 0;
                step2 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_hashOffsetForL3Ecmp_f - IpeEcmpCtl_gLevel1_hashOffsetForL3Ecmp_f : 0;
                step3 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_hashSelectForL3Ecmp_f - IpeEcmpCtl_gLevel1_hashSelectForL3Ecmp_f : 0;
                /*entropy */
                SetIpeEcmpCtl(V, l3PktEcmpUseEntropy_f - step1, &IpeEcmpCtl, use_entropy);

                SetIpeEcmpCtl(V, hashOffsetForL3Ecmp_f - step2, &IpeEcmpCtl, offset);
                SetIpeEcmpCtl(V, hashSelectForL3Ecmp_f - step3, &IpeEcmpCtl, select);
            }
            else
            {
                step1 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_l3PktEcmpUseEntropy_f - DsPortBasedHashProfile0_gEcmpL1_l3PktEcmpUseEntropy_f : 0;
                step2 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_slbL3Valid_f - DsPortBasedHashProfile0_gEcmpL1_slbL3Valid_f : 0;
                step3 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_hashSelectForSlbL3_f - DsPortBasedHashProfile0_gEcmpL1_hashSelectForSlbL3_f : 0;
                step4 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_hashOffsetForSlbL3_f - DsPortBasedHashProfile0_gEcmpL1_hashOffsetForSlbL3_f : 0;
                /*entropy */
                SetDsPortBasedHashProfile0(V, gEcmp_l3PktEcmpUseEntropy_f - step1, &DsPortBasedHashProfile0, use_entropy);

                SetDsPortBasedHashProfile0(V, gEcmp_slbL3Valid_f - step2, &DsPortBasedHashProfile0, offset_valid);
                SetDsPortBasedHashProfile0(V, gEcmp_hashSelectForSlbL3_f - step3, &DsPortBasedHashProfile0, select);
                SetDsPortBasedHashProfile0(V, gEcmp_hashOffsetForSlbL3_f - step4, &DsPortBasedHashProfile0, offset);
            }
        }

        if (!p_hash_offset->hecmp_grp_en && (p_hash_offset->profile_id == CTC_LB_HASH_ECMP_GLOBAL_PROFILE))
        {
            SetIpeFwdCtl(V, entropyHashSelect_f, &IpeFwdCtl, select);
            SetIpeFwdCtl(V, entropyHashOffset_f, &IpeFwdCtl, offset);
        }
        else if(!p_hash_offset->hecmp_grp_en)
        {
            SetDsPortBasedHashProfile0(V, gEntropy_entropyValid_f, &DsPortBasedHashProfile0, offset_valid);
            SetDsPortBasedHashProfile0(V, gEntropy_hashOffsetForEntropy_f, &DsPortBasedHashProfile0, offset);
            SetDsPortBasedHashProfile0(V, gEntropy_hashSelectForEntropy_f, &DsPortBasedHashProfile0, select);
        }

        if (DRV_IS_TSINGMA(lchip) && (SYS_GET_CHIP_VERSION != SYS_CHIP_SUB_VERSION_A))
        {
            IpeFwdReserved_m fwd_rsv;
            uint32 field_value = 0;

            hecmp_select = (select & 0xfe) | ((select & 0x1)?0:1);
            cmd0 = DRV_IOR(IpeFwdReserved_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd0, &fwd_rsv));
            field_value = GetIpeFwdReserved(V, reserved_f, &fwd_rsv);
            field_value &= 0xfffffc7;
            field_value |= ((hecmp_select&0x7) << 3);
            SetIpeFwdReserved(V, reserved_f, &fwd_rsv, field_value);
            cmd0 = DRV_IOW(IpeFwdReserved_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd0, &fwd_rsv));
        }
        break;

    case CTC_LB_HASH_MODE_DLB_FLOW_SET:
        if (p_hash_offset->profile_id == CTC_LB_HASH_ECMP_GLOBAL_PROFILE)
        {
            SetIpeEcmpCtl(V, hashOffsetForFlowIdDlbEcmp_f, &IpeEcmpCtl, offset);
            SetIpeEcmpCtl(V, hashSelectForFlowIdDlbEcmp_f, &IpeEcmpCtl, select);
        }
        else
        {
            dlb_valid = GetDsPortBasedHashProfile0(V, gEcmp_dlbValid_f, &DsPortBasedHashProfile0);
            SetDsPortBasedHashProfile0(V, gEcmp_dlbValid_f, &DsPortBasedHashProfile0, offset_valid ? CTC_BIT_SET(dlb_valid,1) : CTC_BIT_UNSET(dlb_valid,1));
            SetDsPortBasedHashProfile0(V, gEcmp_hashOffsetForDlbFlowId_f, &DsPortBasedHashProfile0, offset);
            SetDsPortBasedHashProfile0(V, gEcmp_hashSelectForDlbFlowId_f, &DsPortBasedHashProfile0, select);
        }
        break;

    case CTC_LB_HASH_MODE_DLB_MEMBER:
        if (p_hash_offset->profile_id == CTC_LB_HASH_ECMP_GLOBAL_PROFILE)
        {
            SetIpeEcmpCtl(V, hashOffsetForHashValueDlbEcmp_f, &IpeEcmpCtl, offset);
            SetIpeEcmpCtl(V, hashSelectForHashValueDlbEcmp_f, &IpeEcmpCtl, select);
        }
        else
        {
            dlb_valid = GetDsPortBasedHashProfile0(V, gEcmp_dlbValid_f, &DsPortBasedHashProfile0);
            SetDsPortBasedHashProfile0(V, gEcmp_dlbValid_f, &DsPortBasedHashProfile0, offset_valid ? CTC_BIT_SET(dlb_valid,0) : CTC_BIT_UNSET(dlb_valid,0));
            SetDsPortBasedHashProfile0(V, gEcmp_hashOffsetForDlbHash_f, &DsPortBasedHashProfile0, offset);
            SetDsPortBasedHashProfile0(V, gEcmp_hashSelectForDlbHash_f, &DsPortBasedHashProfile0, select);
        }
        break;
    default:
        return CTC_E_INVALID_PARAM;
    }

    if (p_hash_offset->profile_id == CTC_LB_HASH_ECMP_GLOBAL_PROFILE)
    {
        cmd0 = DRV_IOW(IpeEcmpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd0, &IpeEcmpCtl));
        cmd0 = DRV_IOW(IpeFwdCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd0, &IpeFwdCtl));
    }
    else
    {
        cmd0 = DRV_IOW(DsPortBasedHashProfile0_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_hash_offset->profile_id, cmd0, &DsPortBasedHashProfile0));
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_hash_get_ecmp_offset(uint8 lchip, ctc_lb_hash_offset_t* p_hash_offset)
{
    uint8 offset = 0;
    uint8 select = 0;
    uint32 cmd0 = 0;
    uint8 use_entropy = 0;
    uint8 step1 = 0;
    uint8 step2 = 0;
    uint8 step3 = 0;
    uint8 step4 = 0;
    uint8 offset_valid = 0;
    DsPortBasedHashProfile0_m DsPortBasedHashProfile0;
    IpeEcmpCtl_m IpeEcmpCtl;

    if (p_hash_offset->profile_id == CTC_LB_HASH_ECMP_GLOBAL_PROFILE)
    {
        sal_memset(&IpeEcmpCtl, 0, sizeof(IpeEcmpCtl));
        cmd0 = DRV_IOR(IpeEcmpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd0, &IpeEcmpCtl));
        offset_valid = 1;
    }
    else
    {
        sal_memset(&DsPortBasedHashProfile0, 0, sizeof(DsPortBasedHashProfile0));
        cmd0 = DRV_IOR(DsPortBasedHashProfile0_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, (p_hash_offset->profile_id), cmd0, &DsPortBasedHashProfile0));
    }


    switch (p_hash_offset->hash_mode)
    {
    case CTC_LB_HASH_MODE_STATIC:
        if (p_hash_offset->fwd_type == CTC_LB_HASH_FWD_VXLAN)
        {
            if (p_hash_offset->profile_id == CTC_LB_HASH_ECMP_GLOBAL_PROFILE)
            {
                step1 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_vxlanEcmpUseEntropy_f - IpeEcmpCtl_gLevel1_vxlanEcmpUseEntropy_f : 0;
                step2 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_hashOffsetForVxlanEcmp_f - IpeEcmpCtl_gLevel1_hashOffsetForVxlanEcmp_f : 0;
                step3 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_hashSelectForVxlanEcmp_f - IpeEcmpCtl_gLevel1_hashSelectForVxlanEcmp_f : 0;
                /*entropy */
                use_entropy = GetIpeEcmpCtl(V, vxlanEcmpUseEntropy_f - step1, &IpeEcmpCtl);

                offset = GetIpeEcmpCtl(V, hashOffsetForVxlanEcmp_f - step2, &IpeEcmpCtl);
                select = GetIpeEcmpCtl(V, hashSelectForVxlanEcmp_f - step3, &IpeEcmpCtl);
            }
            else
            {
                step1 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_vxlanEcmpUseEntropy_f - DsPortBasedHashProfile0_gEcmpL1_vxlanEcmpUseEntropy_f : 0;
                step2 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_hashOffsetForSlbVxlan_f - DsPortBasedHashProfile0_gEcmpL1_hashOffsetForSlbVxlan_f : 0;
                step3 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_hashSelectForSlbVxlan_f - DsPortBasedHashProfile0_gEcmpL1_hashSelectForSlbVxlan_f : 0;
                step4 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_slbVxlanValid_f - DsPortBasedHashProfile0_gEcmpL1_slbVxlanValid_f : 0;
                /*entropy */
                use_entropy = GetDsPortBasedHashProfile0(V, gEcmp_vxlanEcmpUseEntropy_f - step1, &DsPortBasedHashProfile0);

                offset = GetDsPortBasedHashProfile0(V, gEcmp_hashOffsetForSlbVxlan_f - step2, &DsPortBasedHashProfile0);
                select = GetDsPortBasedHashProfile0(V, gEcmp_hashSelectForSlbVxlan_f - step3, &DsPortBasedHashProfile0);
                offset_valid = GetDsPortBasedHashProfile0(V, gEcmp_slbVxlanValid_f - step4, &DsPortBasedHashProfile0);
            }
        }
        else if (p_hash_offset->fwd_type == CTC_LB_HASH_FWD_NVGRE)
        {
            if (p_hash_offset->profile_id == CTC_LB_HASH_ECMP_GLOBAL_PROFILE)
            {
                step1 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_nvgreEcmpUseEntropy_f - IpeEcmpCtl_gLevel1_nvgreEcmpUseEntropy_f : 0;
                step2 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_hashOffsetForNvgreEcmp_f - IpeEcmpCtl_gLevel1_hashOffsetForNvgreEcmp_f : 0;
                step3 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_hashSelectForNvgreEcmp_f - IpeEcmpCtl_gLevel1_hashSelectForNvgreEcmp_f : 0;
                /*entropy */
                use_entropy = GetIpeEcmpCtl(V, nvgreEcmpUseEntropy_f - step1, &IpeEcmpCtl);

                offset = GetIpeEcmpCtl(V, hashOffsetForNvgreEcmp_f - step2, &IpeEcmpCtl);
                select = GetIpeEcmpCtl(V, hashSelectForNvgreEcmp_f - step3, &IpeEcmpCtl);
            }
            else
            {
                step1 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_nvgreEcmpUseEntropy_f - DsPortBasedHashProfile0_gEcmpL1_nvgreEcmpUseEntropy_f : 0;
                step2 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_hashOffsetForSlbNvgre_f - DsPortBasedHashProfile0_gEcmpL1_hashOffsetForSlbNvgre_f : 0;
                step3 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_hashSelectForSlbNvgre_f - DsPortBasedHashProfile0_gEcmpL1_hashSelectForSlbNvgre_f : 0;
                step4 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_slbNvgreValid_f - DsPortBasedHashProfile0_gEcmpL1_slbNvgreValid_f : 0;
                /*entropy */
                use_entropy = GetDsPortBasedHashProfile0(V, gEcmp_nvgreEcmpUseEntropy_f - step1, &DsPortBasedHashProfile0);

                offset = GetDsPortBasedHashProfile0(V, gEcmp_hashOffsetForSlbNvgre_f - step2, &DsPortBasedHashProfile0);
                select = GetDsPortBasedHashProfile0(V, gEcmp_hashSelectForSlbNvgre_f - step3, &DsPortBasedHashProfile0);
                offset_valid = GetDsPortBasedHashProfile0(V, gEcmp_slbNvgreValid_f - step4, &DsPortBasedHashProfile0);
            }
        }
        else if (p_hash_offset->fwd_type == CTC_LB_HASH_FWD_MPLS)
        {
            if (p_hash_offset->profile_id == CTC_LB_HASH_ECMP_GLOBAL_PROFILE)
            {
                step1 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_mplsEcmpUseEntropy_f - IpeEcmpCtl_gLevel1_mplsEcmpUseEntropy_f : 0;
                step2 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_hashOffsetForMplsEcmp_f - IpeEcmpCtl_gLevel1_hashOffsetForMplsEcmp_f : 0;
                step3 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_hashSelectForMplsEcmp_f - IpeEcmpCtl_gLevel1_hashSelectForMplsEcmp_f : 0;
                /*entropy */
                use_entropy = GetIpeEcmpCtl(V, mplsEcmpUseEntropy_f - step1, &IpeEcmpCtl);

                offset = GetIpeEcmpCtl(V, hashOffsetForMplsEcmp_f - step2, &IpeEcmpCtl);
                select = GetIpeEcmpCtl(V, hashSelectForMplsEcmp_f - step3, &IpeEcmpCtl);
            }
            else
            {
                step1 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_mplsEcmpUseEntropy_f - DsPortBasedHashProfile0_gEcmpL1_mplsEcmpUseEntropy_f : 0;
                step2 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_hashOffsetForSlbMpls_f - DsPortBasedHashProfile0_gEcmpL1_hashOffsetForSlbMpls_f : 0;
                step3 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_hashSelectForSlbMpls_f - DsPortBasedHashProfile0_gEcmpL1_hashSelectForSlbMpls_f : 0;
                step4 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_slbMplsValid_f - DsPortBasedHashProfile0_gEcmpL1_slbMplsValid_f : 0;
                /*entropy */
                use_entropy = GetDsPortBasedHashProfile0(V, gEcmp_mplsEcmpUseEntropy_f - step1, &DsPortBasedHashProfile0);

                offset = GetDsPortBasedHashProfile0(V, gEcmp_hashOffsetForSlbMpls_f - step2, &DsPortBasedHashProfile0);
                select = GetDsPortBasedHashProfile0(V, gEcmp_hashSelectForSlbMpls_f - step3, &DsPortBasedHashProfile0);
                offset_valid = GetDsPortBasedHashProfile0(V, gEcmp_slbMplsValid_f - step4, &DsPortBasedHashProfile0);
            }
        }

        else if (p_hash_offset->fwd_type == CTC_LB_HASH_FWD_IP)
        {
            if (p_hash_offset->profile_id == CTC_LB_HASH_ECMP_GLOBAL_PROFILE)
            {
                step1 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_l3PktEcmpUseEntropy_f - IpeEcmpCtl_gLevel1_l3PktEcmpUseEntropy_f : 0;
                step2 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_hashOffsetForL3Ecmp_f - IpeEcmpCtl_gLevel1_hashOffsetForL3Ecmp_f : 0;
                step3 = p_hash_offset->hecmp_grp_en ? IpeEcmpCtl_hashSelectForL3Ecmp_f - IpeEcmpCtl_gLevel1_hashSelectForL3Ecmp_f : 0;
                /*entropy */
                use_entropy = GetIpeEcmpCtl(V, l3PktEcmpUseEntropy_f - step1, &IpeEcmpCtl);

                offset = GetIpeEcmpCtl(V, hashOffsetForL3Ecmp_f - step2, &IpeEcmpCtl);
                select = GetIpeEcmpCtl(V, hashSelectForL3Ecmp_f - step3, &IpeEcmpCtl);
            }
            else
            {
                step1 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_l3PktEcmpUseEntropy_f - DsPortBasedHashProfile0_gEcmpL1_l3PktEcmpUseEntropy_f : 0;
                step2 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_hashOffsetForSlbL3_f - DsPortBasedHashProfile0_gEcmpL1_hashOffsetForSlbL3_f : 0;
                step3 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_hashSelectForSlbL3_f - DsPortBasedHashProfile0_gEcmpL1_hashSelectForSlbL3_f : 0;
                step4 = p_hash_offset->hecmp_grp_en ? DsPortBasedHashProfile0_gEcmp_slbL3Valid_f - DsPortBasedHashProfile0_gEcmpL1_slbL3Valid_f : 0;
                /*entropy */
                use_entropy = GetDsPortBasedHashProfile0(V, gEcmp_l3PktEcmpUseEntropy_f - step1, &DsPortBasedHashProfile0);

                offset = GetDsPortBasedHashProfile0(V, gEcmp_hashOffsetForSlbL3_f - step2, &DsPortBasedHashProfile0);
                select = GetDsPortBasedHashProfile0(V, gEcmp_hashSelectForSlbL3_f - step3, &DsPortBasedHashProfile0);
                offset_valid = GetDsPortBasedHashProfile0(V, gEcmp_slbL3Valid_f - step4, &DsPortBasedHashProfile0);
            }
        }
        else
        {
            return CTC_E_INVALID_PARAM;
        }
        break;

    case CTC_LB_HASH_MODE_DLB_FLOW_SET:
        if (p_hash_offset->profile_id == CTC_LB_HASH_ECMP_GLOBAL_PROFILE)
        {
            offset = GetIpeEcmpCtl(V, hashOffsetForFlowIdDlbEcmp_f, &IpeEcmpCtl);
            select = GetIpeEcmpCtl(V, hashSelectForFlowIdDlbEcmp_f, &IpeEcmpCtl);
        }
        else
        {
            offset = GetDsPortBasedHashProfile0(V, gEcmp_hashOffsetForDlbFlowId_f, &DsPortBasedHashProfile0);
            select = GetDsPortBasedHashProfile0(V, gEcmp_hashSelectForDlbFlowId_f, &DsPortBasedHashProfile0);
            offset_valid = GetDsPortBasedHashProfile0(V, gEcmp_dlbValid_f, &DsPortBasedHashProfile0);
        }
        break;


    case CTC_LB_HASH_MODE_DLB_MEMBER:
        if (p_hash_offset->profile_id == CTC_LB_HASH_ECMP_GLOBAL_PROFILE)
        {
            offset = GetIpeEcmpCtl(V, hashOffsetForHashValueDlbEcmp_f, &IpeEcmpCtl);
            select = GetIpeEcmpCtl(V, hashSelectForHashValueDlbEcmp_f, &IpeEcmpCtl);
        }
        else
        {
            offset = GetDsPortBasedHashProfile0(V, gEcmp_hashOffsetForDlbHash_f, &DsPortBasedHashProfile0);
            select = GetDsPortBasedHashProfile0(V, gEcmp_hashSelectForDlbHash_f, &DsPortBasedHashProfile0);
            offset_valid = GetDsPortBasedHashProfile0(V, gEcmp_dlbValid_f, &DsPortBasedHashProfile0);
        }
        break;
    default:
        return CTC_E_INVALID_PARAM;
    }

    if (offset_valid)
    {
        p_hash_offset->use_packet_head_hash = select>>3;
        p_hash_offset->offset = (select&0x7)*16 + offset;
    }
    else
    {
        p_hash_offset->offset = CTC_LB_HASH_OFFSET_DISABLE;
    }
    p_hash_offset->use_entropy_hash = use_entropy;

  return CTC_E_NONE;
}


STATIC int32
_sys_tsingma_hash_set_packet_head_offset(uint8 lchip, ctc_lb_hash_offset_t* p_hash_offset)
{
    uint8 offset = 0;
    uint8 select = 0;
    uint8 offset_valid = (CTC_LB_HASH_OFFSET_DISABLE == p_hash_offset->offset)? 0: 1;
    uint8 is_global_cfg = ((p_hash_offset->profile_id == 0) || (p_hash_offset->profile_id == CTC_LB_HASH_GLOBAL_PROFILE));
    uint32 cmd0 = 0;
    uint32 cmd1 = 0;
    DsPortBasedHashProfile0_m DsPortBasedHashProfile0;
    IpeFwdCtl_m IpeFwdCtl;

    if (is_global_cfg)
    {
        sal_memset(&IpeFwdCtl, 0, sizeof(IpeFwdCtl));
        cmd1 = DRV_IOR(IpeFwdCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd1, &IpeFwdCtl));
    }
    else
    {
        sal_memset(&DsPortBasedHashProfile0, 0, sizeof(DsPortBasedHashProfile0));
        cmd0 = DRV_IOR(DsPortBasedHashProfile0_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_hash_offset->profile_id, cmd0, &DsPortBasedHashProfile0));
    }

    select = (p_hash_offset->offset) / 16;
    offset = (p_hash_offset->offset) % 16;
    select |= p_hash_offset->use_packet_head_hash ? 8 : 0;

    if ((!offset_valid) && (is_global_cfg))
    {
        CTC_ERROR_RETURN(CTC_E_INVALID_PARAM);
    }

    switch (p_hash_offset->hash_module)
    {
        case CTC_LB_HASH_MODULE_HEAD_LAG:
            if (p_hash_offset->fwd_type == CTC_LB_HASH_FWD_UC)
            {
                if (is_global_cfg)
                {
                    SetIpeFwdCtl(V, lbIdUcHashSelect_f, &IpeFwdCtl, select);
                    SetIpeFwdCtl(V, lbIdUcHashOffset_f, &IpeFwdCtl, offset);
                }
                else
                {
                    SetDsPortBasedHashProfile0(V, gLbid_ucValid_f, &DsPortBasedHashProfile0, offset_valid);
                    SetDsPortBasedHashProfile0(V, gLbid_hashOffsetForUc_f, &DsPortBasedHashProfile0, offset);
                    SetDsPortBasedHashProfile0(V, gLbid_hashSelectForUc_f, &DsPortBasedHashProfile0, select);
                }
            }
            else if(p_hash_offset->fwd_type == CTC_LB_HASH_FWD_NON_UC)
            {
                if (is_global_cfg)
                {
                    SetIpeFwdCtl(V, lbIdNonUcHashSelect_f, &IpeFwdCtl, select);
                    SetIpeFwdCtl(V, lbIdNonUcHashOffset_f, &IpeFwdCtl, offset);
                }
                else
                {
                    SetDsPortBasedHashProfile0(V, gLbid_nonUcValid_f, &DsPortBasedHashProfile0, offset_valid);
                    SetDsPortBasedHashProfile0(V, gLbid_hashOffsetForNonUc_f, &DsPortBasedHashProfile0, offset);
                    SetDsPortBasedHashProfile0(V, gLbid_hashSelectForNonUc_f, &DsPortBasedHashProfile0, select);
                }
            }
            else
            {
                return CTC_E_INVALID_PARAM;
            }

            break;
        case CTC_LB_HASH_MODULE_HEAD_ECMP:
            if (is_global_cfg)
            {
                SetIpeFwdCtl(V, entropyHashSelect_f, &IpeFwdCtl, select);
                SetIpeFwdCtl(V, entropyHashOffset_f, &IpeFwdCtl, offset);
            }
            else
            {
                SetDsPortBasedHashProfile0(V, gEntropy_entropyValid_f, &DsPortBasedHashProfile0, offset_valid);
                SetDsPortBasedHashProfile0(V, gEntropy_hashOffsetForEntropy_f, &DsPortBasedHashProfile0, offset);
                SetDsPortBasedHashProfile0(V, gEntropy_hashSelectForEntropy_f, &DsPortBasedHashProfile0, select);
            }
            break;
        default:
            return CTC_E_INVALID_PARAM;
    }

    if (is_global_cfg)
    {
        cmd1 = DRV_IOW(IpeFwdCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd1, &IpeFwdCtl));
    }
    else
    {
        cmd0 = DRV_IOW(DsPortBasedHashProfile0_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, (p_hash_offset->profile_id), cmd0, &DsPortBasedHashProfile0));
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_hash_get_packet_head_offset(uint8 lchip, ctc_lb_hash_offset_t* p_hash_offset)
{
    uint8 offset = 0;
    uint8 select = 0;
    uint32 cmd0 = 0;
    uint32 cmd1 = 0;
    uint8 is_global_cfg = ((p_hash_offset->profile_id == 0) || (p_hash_offset->profile_id == CTC_LB_HASH_GLOBAL_PROFILE));
    DsPortBasedHashProfile0_m DsPortBasedHashProfile0;
    IpeFwdCtl_m IpeFwdCtl;

    if (is_global_cfg)
    {
        sal_memset(&IpeFwdCtl, 0, sizeof(IpeFwdCtl));
        cmd1 = DRV_IOR(IpeFwdCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd1, &IpeFwdCtl));
    }
    else
    {
        sal_memset(&DsPortBasedHashProfile0, 0, sizeof(DsPortBasedHashProfile0));
        cmd0 = DRV_IOR(DsPortBasedHashProfile0_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_hash_offset->profile_id, cmd0, &DsPortBasedHashProfile0));
    }

    switch (p_hash_offset->hash_module)
    {
        case CTC_LB_HASH_MODULE_HEAD_LAG:
            if (p_hash_offset->fwd_type == CTC_LB_HASH_FWD_UC)
            {
                if (is_global_cfg)
                {
                    select = GetIpeFwdCtl(V, lbIdUcHashSelect_f, &IpeFwdCtl);
                    offset = GetIpeFwdCtl(V, lbIdUcHashOffset_f, &IpeFwdCtl);
                }
                else
                {
                    offset = GetDsPortBasedHashProfile0(V, gLbid_hashOffsetForUc_f, &DsPortBasedHashProfile0);
                    select = GetDsPortBasedHashProfile0(V, gLbid_hashSelectForUc_f, &DsPortBasedHashProfile0);
                }
            }
            else if(p_hash_offset->fwd_type == CTC_LB_HASH_FWD_NON_UC)
            {
                if (is_global_cfg)
                {
                    select = GetIpeFwdCtl(V, lbIdNonUcHashSelect_f, &IpeFwdCtl);
                    offset = GetIpeFwdCtl(V, lbIdNonUcHashOffset_f, &IpeFwdCtl);
                }
                else
                {
                    offset = GetDsPortBasedHashProfile0(V, gLbid_hashOffsetForNonUc_f, &DsPortBasedHashProfile0);
                    select = GetDsPortBasedHashProfile0(V, gLbid_hashSelectForNonUc_f, &DsPortBasedHashProfile0);
                }
            }
            else
            {
                return CTC_E_INVALID_PARAM;
            }

            break;
        case CTC_LB_HASH_MODULE_HEAD_ECMP:
            if (is_global_cfg)
            {
                select = GetIpeFwdCtl(V, entropyHashSelect_f, &IpeFwdCtl);
                offset = GetIpeFwdCtl(V, entropyHashOffset_f, &IpeFwdCtl);
            }
            else
            {
                offset = GetDsPortBasedHashProfile0(V, gEntropy_hashOffsetForEntropy_f, &DsPortBasedHashProfile0);
                select = GetDsPortBasedHashProfile0(V, gEntropy_hashSelectForEntropy_f, &DsPortBasedHashProfile0);
            }

            break;
        default:
            return CTC_E_INVALID_PARAM;
    }

    p_hash_offset->use_packet_head_hash = select>>3;
    p_hash_offset->offset = (select&0x7)*16 + offset;

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_hash_set_lag_non_uc_offset(uint8 lchip, ctc_lb_hash_offset_t* p_hash_offset)
{
    uint8 offset = 0;
    uint8 select = 0;
    uint32 cmd0 = 0;
    uint32 cmd1 = 0;
    uint8 offset_valid = (CTC_LB_HASH_OFFSET_DISABLE == p_hash_offset->offset)? 0: 1;
    uint8 is_global_cfg = ((p_hash_offset->profile_id == 0) || (p_hash_offset->profile_id == CTC_LB_HASH_GLOBAL_PROFILE));
    DsPortBasedHashProfile0_m DsPortBasedHashProfile0;
    IpeFwdCtl_m IpeFwdCtl;

    if (is_global_cfg)
    {
        sal_memset(&IpeFwdCtl, 0, sizeof(IpeFwdCtl));
        cmd1 = DRV_IOR(IpeFwdCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd1, &IpeFwdCtl));
    }
    else
    {
    	sal_memset(&DsPortBasedHashProfile0, 0, sizeof(DsPortBasedHashProfile0));
        cmd0 = DRV_IOR(DsPortBasedHashProfile0_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, (p_hash_offset->profile_id), cmd0, &DsPortBasedHashProfile0));
    }

    select = (p_hash_offset->offset) / 16;
    offset = (p_hash_offset->offset) % 16;
    select |= p_hash_offset->use_packet_head_hash ? 8 : 0;

    switch (p_hash_offset->hash_mode)
    {
        case CTC_LB_HASH_MODE_STATIC:
            if (is_global_cfg)
            {
                SetIpeFwdCtl(V, lbIdNonUcHashSelect_f, &IpeFwdCtl, select);
                SetIpeFwdCtl(V, lbIdNonUcHashOffset_f, &IpeFwdCtl, offset);
            }
            else
            {
                SetDsPortBasedHashProfile0(V, gLbid_nonUcValid_f, &DsPortBasedHashProfile0, offset_valid);
                SetDsPortBasedHashProfile0(V, gLbid_hashOffsetForNonUc_f, &DsPortBasedHashProfile0, offset);
                SetDsPortBasedHashProfile0(V, gLbid_hashSelectForNonUc_f, &DsPortBasedHashProfile0, select);
            }
            break;
        case CTC_LB_HASH_MODE_LSH:
            if (is_global_cfg)
            {
                SetIpeFwdCtl(V, portLagLshNonUcHashSelect_f, &IpeFwdCtl, select);
                SetIpeFwdCtl(V, portLagLshNonUcHashOffset_f, &IpeFwdCtl, offset);
            }
            else
            {
                SetDsPortBasedHashProfile0(V, gPortLagLsh_nonUcValid_f, &DsPortBasedHashProfile0, offset_valid);
                SetDsPortBasedHashProfile0(V, gPortLagLsh_hashSelectForNonUc_f, &DsPortBasedHashProfile0, select);
                SetDsPortBasedHashProfile0(V, gPortLagLsh_hashOffsetForNonUc_f, &DsPortBasedHashProfile0, offset);
            }
            break;
        default:
            break;
    }


    if (is_global_cfg)
    {
        cmd1 = DRV_IOW(IpeFwdCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd1, &IpeFwdCtl));
    }
    else
    {
        cmd0 = DRV_IOW(DsPortBasedHashProfile0_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, (p_hash_offset->profile_id), cmd0, &DsPortBasedHashProfile0));
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_hash_get_lag_non_uc_offset(uint8 lchip, ctc_lb_hash_offset_t* p_hash_offset)
{
    uint8 offset = 0;
    uint8 select = 0;
    uint32 cmd0 = 0;
    uint32 cmd1 = 0;
    uint8 is_global_cfg = ((p_hash_offset->profile_id == 0) || (p_hash_offset->profile_id == CTC_LB_HASH_GLOBAL_PROFILE));
    DsPortBasedHashProfile0_m DsPortBasedHashProfile0;
    IpeFwdCtl_m IpeFwdCtl;


    if (is_global_cfg)
    {
        sal_memset(&IpeFwdCtl, 0, sizeof(IpeFwdCtl));
        cmd1 = DRV_IOR(IpeFwdCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd1, &IpeFwdCtl));
    }
    else
    {
        sal_memset(&DsPortBasedHashProfile0, 0, sizeof(DsPortBasedHashProfile0));
        cmd0 = DRV_IOR(DsPortBasedHashProfile0_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_hash_offset->profile_id, cmd0, &DsPortBasedHashProfile0));
    }


    switch (p_hash_offset->hash_mode)
    {
        case CTC_LB_HASH_MODE_STATIC:
           if (is_global_cfg)
            {
                select = GetIpeFwdCtl(V, lbIdNonUcHashSelect_f, &IpeFwdCtl);
                offset = GetIpeFwdCtl(V, lbIdNonUcHashOffset_f, &IpeFwdCtl);
            }
            else
            {
                offset = GetDsPortBasedHashProfile0(V, gLbid_hashOffsetForNonUc_f, &DsPortBasedHashProfile0);
                select = GetDsPortBasedHashProfile0(V, gLbid_hashSelectForNonUc_f, &DsPortBasedHashProfile0);
            }
            break;
        case CTC_LB_HASH_MODE_LSH:
            if(is_global_cfg)
            {
                select = GetIpeFwdCtl(V, portLagLshNonUcHashSelect_f, &IpeFwdCtl);
                offset = GetIpeFwdCtl(V, portLagLshNonUcHashOffset_f, &IpeFwdCtl);
            }
            else
            {
                select = GetDsPortBasedHashProfile0(V, gPortLagLsh_hashSelectForNonUc_f, &DsPortBasedHashProfile0);
                offset = GetDsPortBasedHashProfile0(V, gPortLagLsh_hashOffsetForNonUc_f, &DsPortBasedHashProfile0);
            }
            break;

        default:
            break;
    }

    p_hash_offset->use_packet_head_hash = select>>3;
    p_hash_offset->offset = (select&0x7)*16 + offset;

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_hash_set_stacking_offset(uint8 lchip, ctc_lb_hash_offset_t* p_hash_offset, uint8 fwd_type)
{
    uint8 offset = 0;
    uint8 select = 0;
    uint8 offset_valid = (CTC_LB_HASH_OFFSET_DISABLE == p_hash_offset->offset)? 0: 1;
    uint8 is_global_cfg = ((p_hash_offset->profile_id == 0) || (p_hash_offset->profile_id == CTC_LB_HASH_GLOBAL_PROFILE));
    uint32 cmd = 0;
    IpeFwdCflexUplinkLagHashCtl_m hash_ctl;

    if(!offset_valid && !DRV_FROM_TMM(lchip))
    {
        CTC_ERROR_RETURN(CTC_E_INVALID_PARAM);
    }

    select = (p_hash_offset->offset) / 16;
    offset = (p_hash_offset->offset) % 16;
    select |= p_hash_offset->use_packet_head_hash ? 8 : 0;

    sal_memset(&hash_ctl, 0, sizeof(hash_ctl));
    cmd = DRV_IOR(IpeFwdCflexUplinkLagHashCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hash_ctl));

    if (!fwd_type)
    {
        /*uc*/
        if (is_global_cfg)
        {
            SetIpeFwdCflexUplinkLagHashCtl(V, gFwdType_0_hashOffsetCfg_f, &hash_ctl, offset);
            SetIpeFwdCflexUplinkLagHashCtl(V, gFwdType_0_hashSelectCfg_f, &hash_ctl, select);
            SetIpeFwdCflexUplinkLagHashCtl(V, gFwdType_1_hashOffsetCfg_f, &hash_ctl, offset);
            SetIpeFwdCflexUplinkLagHashCtl(V, gFwdType_1_hashSelectCfg_f, &hash_ctl, select);

            cmd = DRV_IOW(IpeFwdCflexUplinkLagHashCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hash_ctl));
        }
        else
        {
            DsPortBasedHashProfile1_m DsPortBasedHashProfile1;
            cmd = DRV_IOR(DsPortBasedHashProfile1_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, (p_hash_offset->profile_id), cmd, &DsPortBasedHashProfile1));

            switch (p_hash_offset->hash_mode)
            {
                case CTC_LB_HASH_MODE_STATIC:
                    SetDsPortBasedHashProfile1(V, gLag_1_slbValid_f, &DsPortBasedHashProfile1, offset_valid);
                    SetDsPortBasedHashProfile1(V, gLag_1_hashSelectForSlb_f, &DsPortBasedHashProfile1, select);
                    SetDsPortBasedHashProfile1(V, gLag_1_hashOffsetForSlb_f, &DsPortBasedHashProfile1, offset);
                    break;

                case CTC_LB_HASH_MODE_DLB_FLOW_SET:
                    SetDsPortBasedHashProfile1(V, gLag_1_dlbValid_f, &DsPortBasedHashProfile1, offset_valid);
                    SetDsPortBasedHashProfile1(V, gLag_1_hashSelectForDlb_f, &DsPortBasedHashProfile1, select);
                    SetDsPortBasedHashProfile1(V, gLag_1_hashOffsetForDlb_f, &DsPortBasedHashProfile1, offset);
                    break;

                case CTC_LB_HASH_MODE_LSH:
                    SetDsPortBasedHashProfile1(V, cflexLagLshValid_f, &DsPortBasedHashProfile1, offset_valid);
                    SetDsPortBasedHashProfile1(V, hashSelectForCflexLagLsh_f, &DsPortBasedHashProfile1, select);
                    SetDsPortBasedHashProfile1(V, hashOffsetForCflexLagLsh_f, &DsPortBasedHashProfile1, offset);
                    break;

                default:
                    return CTC_E_INVALID_PARAM;
            }

            cmd = DRV_IOW(DsPortBasedHashProfile1_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, (p_hash_offset->profile_id), cmd, &DsPortBasedHashProfile1));
        }
    }
    else
    {
         /*non-uc*/
        if(DRV_FROM_TMM(lchip))
        {
            DsPortBasedHashProfile0_m DsPortBasedHashProfile0;
            IpeFwdCtl_m IpeFwdCtl;

            if(is_global_cfg)
            {
                sal_memset(&IpeFwdCtl, 0, sizeof(IpeFwdCtl));
                cmd = DRV_IOR(IpeFwdCtl_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &IpeFwdCtl));
            }
            else
            {
            	sal_memset(&DsPortBasedHashProfile0, 0, sizeof(DsPortBasedHashProfile0));
                cmd = DRV_IOR(DsPortBasedHashProfile0_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, (p_hash_offset->profile_id), cmd, &DsPortBasedHashProfile0));
            }

            switch (p_hash_offset->hash_mode)
            {
                case CTC_LB_HASH_MODE_STATIC:
                    if(is_global_cfg)
                    {
                        SetIpeFwdCtl(V, cflexLagSlbNonUcHashSelect_f, &IpeFwdCtl, select);
                        SetIpeFwdCtl(V, cflexLagSlbNonUcHashOffset_f, &IpeFwdCtl, offset);
                    }
                    else
                    {
                        SetDsPortBasedHashProfile0(V, gCflexLagSlb_nonUcValid_f, &DsPortBasedHashProfile0, offset_valid);
                    	SetDsPortBasedHashProfile0(V, gCflexLagSlb_hashSelectForNonUc_f, &DsPortBasedHashProfile0, select);
                    	SetDsPortBasedHashProfile0(V, gCflexLagSlb_hashOffsetForNonUc_f, &DsPortBasedHashProfile0, offset);
                    }
                    break;

                case CTC_LB_HASH_MODE_LSH:
                    if(is_global_cfg)
                    {
                        SetIpeFwdCtl(V, cflexLagLshNonUcHashSelect_f, &IpeFwdCtl, select);
                        SetIpeFwdCtl(V, cflexLagLshNonUcHashOffset_f, &IpeFwdCtl, offset);
                    }
                    else
                    {
                        SetDsPortBasedHashProfile0(V, gCflexLagLsh_nonUcValid_f, &DsPortBasedHashProfile0, offset_valid);
                        SetDsPortBasedHashProfile0(V, gCflexLagLsh_hashSelectForNonUc_f, &DsPortBasedHashProfile0, select);
                        SetDsPortBasedHashProfile0(V, gCflexLagLsh_hashOffsetForNonUc_f, &DsPortBasedHashProfile0, offset);
                    }
                    break;
                default:
                    return CTC_E_INVALID_PARAM;
            }

            if(is_global_cfg)
            {
                cmd = DRV_IOW(IpeFwdCtl_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &IpeFwdCtl));
            }
            else
            {
                cmd = DRV_IOW(DsPortBasedHashProfile0_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, (p_hash_offset->profile_id), cmd, &DsPortBasedHashProfile0));
            }
        }
        else
        {
            SetIpeFwdCflexUplinkLagHashCtl(V, gFwdType_2_hashOffsetCfg_f, &hash_ctl, offset);
            SetIpeFwdCflexUplinkLagHashCtl(V, gFwdType_2_hashSelectCfg_f, &hash_ctl, select);

            cmd = DRV_IOW(IpeFwdCflexUplinkLagHashCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hash_ctl));
        }
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_hash_get_stacking_offset(uint8 lchip, ctc_lb_hash_offset_t* p_hash_offset, uint8 fwd_type)
{
    uint8 offset = 0;
    uint8 select = 0;
    uint32 cmd = 0;
    uint8 is_global_cfg = ((p_hash_offset->profile_id == 0) || (p_hash_offset->profile_id == CTC_LB_HASH_GLOBAL_PROFILE));
    IpeFwdCflexUplinkLagHashCtl_m hash_ctl;

    sal_memset(&hash_ctl, 0, sizeof(hash_ctl));
    cmd = DRV_IOR(IpeFwdCflexUplinkLagHashCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hash_ctl));

    if (!fwd_type)
    {
        /*uc*/
        if (is_global_cfg)
        {
            offset = GetIpeFwdCflexUplinkLagHashCtl(V, gFwdType_0_hashOffsetCfg_f, &hash_ctl);
            select = GetIpeFwdCflexUplinkLagHashCtl(V, gFwdType_0_hashSelectCfg_f, &hash_ctl);
        }
        else
        {
            DsPortBasedHashProfile1_m DsPortBasedHashProfile1;
            cmd = DRV_IOR(DsPortBasedHashProfile1_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, (p_hash_offset->profile_id), cmd, &DsPortBasedHashProfile1));

            switch (p_hash_offset->hash_mode)
            {
                case CTC_LB_HASH_MODE_STATIC:
                    select = GetDsPortBasedHashProfile1(V, gLag_1_hashSelectForSlb_f, &DsPortBasedHashProfile1);
                    offset = GetDsPortBasedHashProfile1(V, gLag_1_hashOffsetForSlb_f, &DsPortBasedHashProfile1);
                    break;

                case CTC_LB_HASH_MODE_DLB_FLOW_SET:
                    select = GetDsPortBasedHashProfile1(V, gLag_1_hashSelectForDlb_f, &DsPortBasedHashProfile1);
                    offset = GetDsPortBasedHashProfile1(V, gLag_1_hashOffsetForDlb_f, &DsPortBasedHashProfile1);
                    break;

                case CTC_LB_HASH_MODE_LSH:
                    select = GetDsPortBasedHashProfile1(V, hashSelectForCflexLagLsh_f, &DsPortBasedHashProfile1);
                    offset = GetDsPortBasedHashProfile1(V, hashOffsetForCflexLagLsh_f, &DsPortBasedHashProfile1);
                    break;

                default:
                    return CTC_E_INVALID_PARAM;
            }
        }
    }
    else
    {
	 /*non-uc*/
        if(DRV_FROM_TMM(lchip))
        {
            DsPortBasedHashProfile0_m DsPortBasedHashProfile0;
            IpeFwdCtl_m IpeFwdCtl;

            if(is_global_cfg)
            {
                sal_memset(&IpeFwdCtl, 0, sizeof(IpeFwdCtl));
                cmd = DRV_IOR(IpeFwdCtl_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &IpeFwdCtl));
            }
            else
            {
            	sal_memset(&DsPortBasedHashProfile0, 0, sizeof(DsPortBasedHashProfile0));
                cmd = DRV_IOR(DsPortBasedHashProfile0_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, (p_hash_offset->profile_id), cmd, &DsPortBasedHashProfile0));
            }

            switch (p_hash_offset->hash_mode)
            {
                case CTC_LB_HASH_MODE_STATIC:
                    if(is_global_cfg)
                    {
                        select = GetIpeFwdCtl(V, cflexLagSlbNonUcHashSelect_f, &IpeFwdCtl);
                        offset = GetIpeFwdCtl(V, cflexLagSlbNonUcHashOffset_f, &IpeFwdCtl);
                    }
                    else
                    {
                        select = GetDsPortBasedHashProfile0(V, gCflexLagSlb_hashSelectForNonUc_f, &DsPortBasedHashProfile0);
                        offset = GetDsPortBasedHashProfile0(V, gCflexLagSlb_hashOffsetForNonUc_f, &DsPortBasedHashProfile0);
                    }
                    break;

                case CTC_LB_HASH_MODE_LSH:
                    if(is_global_cfg)
                    {
                        select = GetIpeFwdCtl(V, cflexLagLshNonUcHashSelect_f, &IpeFwdCtl);
                        offset = GetIpeFwdCtl(V, cflexLagLshNonUcHashOffset_f, &IpeFwdCtl);
                    }
                    else
                    {
                        select = GetDsPortBasedHashProfile0(V, gCflexLagLsh_hashSelectForNonUc_f, &DsPortBasedHashProfile0);
                        offset = GetDsPortBasedHashProfile0(V, gCflexLagLsh_hashOffsetForNonUc_f, &DsPortBasedHashProfile0);
                    }
                    break;

                default:
                    return CTC_E_INVALID_PARAM;
            }
        }
        else
        {
            offset = GetIpeFwdCflexUplinkLagHashCtl(V, gFwdType_2_hashOffsetCfg_f, &hash_ctl);
            select = GetIpeFwdCflexUplinkLagHashCtl(V, gFwdType_2_hashSelectCfg_f, &hash_ctl);
        }
    }
    p_hash_offset->use_packet_head_hash = select>>3;
    p_hash_offset->offset = (select&0x7)*16 + offset;


    return CTC_E_NONE;
}



int32
sys_tsingma_hash_set_offset(uint8 lchip, void* p_hash_offset_param)
{
      ctc_lb_hash_offset_t* p_hash_offset = 0;

      p_hash_offset = (ctc_lb_hash_offset_t*) p_hash_offset_param;

      CTC_PTR_VALID_CHECK(p_hash_offset);
      if ((p_hash_offset->profile_id > MCHIP_CAP(SYS_CAP_LB_HASH_PROFILE_ID_MAX)) && (p_hash_offset->profile_id != CTC_LB_HASH_GLOBAL_PROFILE))
      {
          return CTC_E_INVALID_PARAM;
      }
      if ((CTC_LB_HASH_MODULE_LINKAGG == p_hash_offset->hash_module) && (CTC_LB_HASH_FWD_UC == p_hash_offset->fwd_type) 
        && (p_hash_offset->profile_id > MCHIP_CAP(SYS_CAP_LB_HASH_PROFILE_ID_MAX)))
      {
          return CTC_E_INVALID_PARAM;
      }

      SYS_USW_LB_HASH_CHK_OFFSET(p_hash_offset->offset);

      if (p_hash_offset->use_entropy_hash &&
          !(p_hash_offset->hash_module == CTC_LB_HASH_MODULE_ECMP &&
      p_hash_offset->hash_mode == CTC_LB_HASH_MODE_STATIC))
      {
          return CTC_E_FEATURE_NOT_SUPPORT;
      }

      switch (p_hash_offset->hash_module)
      {
          case CTC_LB_HASH_MODULE_LINKAGG:
              if (p_hash_offset->fwd_type == CTC_LB_HASH_FWD_NON_UC)
              {
                CTC_ERROR_RETURN(_sys_tsingma_hash_set_lag_non_uc_offset(lchip, p_hash_offset));
              }
              else if(p_hash_offset->fwd_type == CTC_LB_HASH_FWD_UC)
              {
                CTC_ERROR_RETURN(_sys_tsingma_hash_set_lag_offset(lchip, p_hash_offset));
              }
              break;

          case CTC_LB_HASH_MODULE_STACKING:
              if (p_hash_offset->fwd_type == CTC_LB_HASH_FWD_NON_UC)
              {
                  CTC_ERROR_RETURN(_sys_tsingma_hash_set_stacking_offset(lchip, p_hash_offset, 1));
              }
              else if (p_hash_offset->fwd_type == CTC_LB_HASH_FWD_UC)
              {
                  CTC_ERROR_RETURN(_sys_tsingma_hash_set_stacking_offset(lchip, p_hash_offset, 0));
              }
              break;

          case CTC_LB_HASH_MODULE_ECMP:
              CTC_ERROR_RETURN(_sys_tsingma_hash_set_ecmp_offset(lchip, p_hash_offset));
              break;

          case CTC_LB_HASH_MODULE_HEAD_LAG:
          case CTC_LB_HASH_MODULE_HEAD_ECMP:
              CTC_ERROR_RETURN(_sys_tsingma_hash_set_packet_head_offset(lchip, p_hash_offset));
              break;

          default:
              return CTC_E_INVALID_PARAM;
      }

      return CTC_E_NONE;
}

int32
sys_tsingma_hash_get_offset(uint8 lchip, void* p_hash_offset_param)
{
    ctc_lb_hash_offset_t* p_hash_offset = 0;

    p_hash_offset = (ctc_lb_hash_offset_t*) p_hash_offset_param;

    CTC_PTR_VALID_CHECK(p_hash_offset);
    if ((p_hash_offset->profile_id > MCHIP_CAP(SYS_CAP_LB_HASH_PROFILE_ID_MAX)) && (p_hash_offset->profile_id != CTC_LB_HASH_GLOBAL_PROFILE))
    {
        return CTC_E_INVALID_PARAM;
    }
    if ((CTC_LB_HASH_MODULE_LINKAGG == p_hash_offset->hash_module) && (CTC_LB_HASH_FWD_UC == p_hash_offset->fwd_type) 
        && (p_hash_offset->profile_id > MCHIP_CAP(SYS_CAP_LB_HASH_PROFILE_ID_MAX)))
    {
        return CTC_E_INVALID_PARAM;
    }

    switch (p_hash_offset->hash_module)
    {
        case CTC_LB_HASH_MODULE_LINKAGG:
            if (p_hash_offset->fwd_type == CTC_LB_HASH_FWD_NON_UC)
            {
                CTC_ERROR_RETURN(_sys_tsingma_hash_get_lag_non_uc_offset(lchip, p_hash_offset));
            }
            else
            {
                CTC_ERROR_RETURN(_sys_tsingma_hash_get_lag_offset(lchip, p_hash_offset));
            }
            break;

        case CTC_LB_HASH_MODULE_STACKING:
            if (p_hash_offset->fwd_type == CTC_LB_HASH_FWD_NON_UC)
            {
                CTC_ERROR_RETURN(_sys_tsingma_hash_get_stacking_offset(lchip, p_hash_offset, 1));
            }
            else if (p_hash_offset->fwd_type == CTC_LB_HASH_FWD_UC)
            {
                CTC_ERROR_RETURN(_sys_tsingma_hash_get_stacking_offset(lchip, p_hash_offset, 0));
            }
            break;

        case CTC_LB_HASH_MODULE_ECMP:
            CTC_ERROR_RETURN(_sys_tsingma_hash_get_ecmp_offset(lchip, p_hash_offset));
            break;

        case CTC_LB_HASH_MODULE_HEAD_LAG:
        case CTC_LB_HASH_MODULE_HEAD_ECMP:
            CTC_ERROR_RETURN(_sys_tsingma_hash_get_packet_head_offset(lchip, p_hash_offset));
            break;

        default:
            return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_parser_set_layer2_hash(uint8 lchip,
                                    ctc_parser_hash_ctl_t* p_psc,
                                    sys_parser_hash_usage_t hash_usage)
{
    uint32 value = 0;
    ctc_lb_hash_config_t hash_cfg;
    uint32  useless_flag = 0;
    sal_memset(&hash_cfg, 0, sizeof(hash_cfg));

    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_SELECT;
    hash_cfg.sel_id = hash_usage;

    value = CTC_FLAG_ISSET(p_psc->l2_flag, CTC_PARSER_L2_HASH_FLAGS_STAG_VID);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_SVLAN : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag, CTC_PARSER_L2_HASH_FLAGS_CTAG_VID);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_CVLAN : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag , CTC_PARSER_L2_HASH_FLAGS_ETHERTYPE);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_ETHER_TYPE : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag, CTC_PARSER_L2_HASH_FLAGS_MACSA);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_MACSA_LO : 0));
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_MACSA_MI : 0));
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_MACSA_HI : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_MACDA);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_MACDA_LO : 0));
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_MACDA_MI : 0));
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_MACDA_HI : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_PORT);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_SRC_PORT : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_DST_PORT);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_DST_PORT : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_SRC_CHIP_ID);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_SRC_CHIP_ID : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_DST_CHIP_ID);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_DST_CHIP_ID : 0));
    
    hash_cfg.hash_select = CTC_LB_HASH_SELECT_L2;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    hash_cfg.hash_select = CTC_LB_HASH_SELECT_NVGRE_INNER_L2;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    hash_cfg.hash_select = CTC_LB_HASH_SELECT_VXLAN_INNER_L2;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    hash_cfg.hash_select = CTC_LB_HASH_SELECT_MPLS_L2VPN_INNER_L2;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    hash_cfg.hash_select = CTC_LB_HASH_SELECT_TRILL_OUTER_L2_ONLY;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    hash_cfg.hash_select = CTC_LB_HASH_SELECT_TRILL;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    hash_cfg.hash_select = CTC_LB_HASH_SELECT_TRILL_INNER_L2;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    hash_cfg.hash_select = CTC_LB_HASH_SELECT_TRILL_DECAP_INNER_L2;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    hash_cfg.hash_select = CTC_LB_HASH_SELECT_FLEX_TNL_INNER_L2;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    CTC_SET_FLAG(useless_flag,  CTC_PARSER_L2_HASH_FLAGS_COS);
    CTC_SET_FLAG(useless_flag,  CTC_PARSER_L2_HASH_FLAGS_CTAG_CFI);
    CTC_SET_FLAG(useless_flag,  CTC_PARSER_L2_HASH_FLAGS_CTAG_COS);
    CTC_SET_FLAG(useless_flag,  CTC_PARSER_L2_HASH_FLAGS_STAG_CFI);
    CTC_SET_FLAG(useless_flag,  CTC_PARSER_L2_HASH_FLAGS_STAG_COS);
    if (p_psc->l2_flag & useless_flag)
    {
        CTC_UNSET_FLAG(p_psc->l2_flag, useless_flag);
        return CTC_E_PARTIAL_PARAM;
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_parser_get_layer2_hash(uint8 lchip,
                                    ctc_parser_hash_ctl_t* p_psc,
                                    sys_parser_hash_usage_t hash_usage)
{
    uint32 value = 0;
    ctc_lb_hash_config_t hash_cfg;

    sal_memset(&hash_cfg, 0, sizeof(hash_cfg));
    hash_cfg.sel_id = hash_usage;

    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_SELECT;

    hash_cfg.hash_select = CTC_LB_HASH_SELECT_L2;
    CTC_ERROR_RETURN(sys_tsingma_hash_get_config(lchip, &hash_cfg));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_SVLAN);
    CTC_SET_FLAG(p_psc->l2_flag, (value ? CTC_PARSER_L2_HASH_FLAGS_STAG_VID : 0));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_CVLAN);
    CTC_SET_FLAG(p_psc->l2_flag, (value ? CTC_PARSER_L2_HASH_FLAGS_CTAG_VID : 0));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_ETHER_TYPE);
    CTC_SET_FLAG(p_psc->l2_flag, (value ? CTC_PARSER_L2_HASH_FLAGS_ETHERTYPE : 0));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_MACSA_LO);
    value &= CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_MACSA_MI);
    value &= CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_MACSA_HI);
    CTC_SET_FLAG(p_psc->l2_flag, (value ? CTC_PARSER_L2_HASH_FLAGS_MACSA : 0));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_MACDA_LO);
    value &= CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_MACDA_MI);
    value &= CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_MACDA_HI);
    CTC_SET_FLAG(p_psc->l2_flag, (value ? CTC_PARSER_L2_HASH_FLAGS_MACDA : 0));

    value = CTC_FLAG_ISSET(hash_cfg.value,  CTC_LB_HASH_FIELD_SRC_PORT);
    CTC_SET_FLAG(p_psc->l2_flag, (value ? CTC_PARSER_L2_HASH_FLAGS_PORT : 0));

    value = CTC_FLAG_ISSET(hash_cfg.value,  CTC_LB_HASH_FIELD_DST_PORT);
    CTC_SET_FLAG(p_psc->l2_flag, (value ? CTC_PARSER_L2_HASH_FLAGS_DST_PORT : 0));

    value = CTC_FLAG_ISSET(hash_cfg.value,  CTC_LB_HASH_FIELD_SRC_CHIP_ID);
    CTC_SET_FLAG(p_psc->l2_flag, (value ? CTC_PARSER_L2_HASH_FLAGS_SRC_CHIP_ID : 0));

    value = CTC_FLAG_ISSET(hash_cfg.value,  CTC_LB_HASH_FIELD_DST_CHIP_ID);
    CTC_SET_FLAG(p_psc->l2_flag, (value ? CTC_PARSER_L2_HASH_FLAGS_DST_CHIP_ID : 0));
    return CTC_E_NONE;
}


STATIC int32
_sys_tsingma_parser_set_l3_l4_hash(uint8 lchip, ctc_parser_hash_ctl_t* p_psc,
                                sys_parser_hash_usage_t hash_usage)
{
    uint32 value = 0;
    ctc_lb_hash_config_t hash_cfg;
    ctc_lb_hash_config_t hash_cfg_gre;
    ctc_lb_hash_config_t hash_cfg_nvgre;
    uint8 use_template_gre = 0;
    uint8 use_template_ip = 0;
    uint8 l3_info_en = 0;
    uint32 useless_flag    = 0;
    uint8 i = 0;
    uint32 template_ip[] = {
        CTC_LB_HASH_SELECT_IPV4,
        CTC_LB_HASH_SELECT_IPV4_TCP_UDP,
        CTC_LB_HASH_SELECT_IPV4_TCP_UDP_PORTS_EQUAL,
        CTC_LB_HASH_SELECT_IPV4_VXLAN,
        CTC_LB_HASH_SELECT_IPV6,
        CTC_LB_HASH_SELECT_IPV6_TCP_UDP,
        CTC_LB_HASH_SELECT_IPV6_TCP_UDP_PORTS_EQUAL,
        CTC_LB_HASH_SELECT_IPV6_VXLAN,
        CTC_LB_HASH_SELECT_NVGRE_INNER_IPV4,
        CTC_LB_HASH_SELECT_NVGRE_INNER_IPV6,
        CTC_LB_HASH_SELECT_VXLAN_INNER_IPV4,
        CTC_LB_HASH_SELECT_VXLAN_INNER_IPV6,
        CTC_LB_HASH_SELECT_MPLS_L2VPN_INNER_IPV4,
        CTC_LB_HASH_SELECT_MPLS_L2VPN_INNER_IPV6,
        CTC_LB_HASH_SELECT_MPLS_L3VPN_INNER_IPV4,
        CTC_LB_HASH_SELECT_MPLS_L3VPN_INNER_IPV6,
        CTC_LB_HASH_SELECT_TRILL_INNER_IPV4,
        CTC_LB_HASH_SELECT_TRILL_INNER_IPV6,
        CTC_LB_HASH_SELECT_TRILL_DECAP_INNER_IPV4,
        CTC_LB_HASH_SELECT_TRILL_DECAP_INNER_IPV6,
        CTC_LB_HASH_SELECT_FLEX_TNL_INNER_IPV4,
        CTC_LB_HASH_SELECT_FLEX_TNL_INNER_IPV6
        };
    sal_memset(&hash_cfg, 0, sizeof(hash_cfg));

    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_SELECT;
    hash_cfg.sel_id = hash_usage;

    if (CTC_FLAG_ISSET(p_psc->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_IP))
    {
        value = CTC_FLAG_ISSET(p_psc->ip_flag, CTC_PARSER_IP_HASH_FLAGS_PROTOCOL);
        CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_PROTOCOL : 0));

        value = CTC_FLAG_ISSET(p_psc->ip_flag, CTC_PARSER_IP_HASH_FLAGS_IPV6_FLOW_LABEL);
        CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_FLOWLABEL_LO : 0));
        CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_FLOWLABEL_HI : 0));

        value = CTC_FLAG_ISSET(p_psc->ip_flag, CTC_PARSER_IP_HASH_FLAGS_IPSA);
        CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_IP_SA_LO : 0));
        CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_IP_SA_HI : 0));

        value = CTC_FLAG_ISSET(p_psc->ip_flag , CTC_PARSER_IP_HASH_FLAGS_IPDA);
        CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_IP_DA_LO : 0));
        CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_IP_DA_HI : 0));
        l3_info_en = 1;
    }
    sal_memcpy(&hash_cfg_nvgre, &hash_cfg , sizeof(ctc_lb_hash_config_t));
    sal_memcpy(&hash_cfg_gre, &hash_cfg , sizeof(ctc_lb_hash_config_t));
    if (CTC_FLAG_ISSET(p_psc->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_L4))
    {
        if (CTC_FLAG_ISSET(p_psc->l4_flag, CTC_PARSER_L4_HASH_FLAGS_GRE_KEY) ||
            CTC_FLAG_ISSET(p_psc->l4_flag, CTC_PARSER_L4_HASH_FLAGS_L4_NVGRE_VSID))
        {
            value = CTC_FLAG_ISSET(p_psc->l4_flag, CTC_PARSER_L4_HASH_FLAGS_GRE_KEY);
            CTC_SET_FLAG(hash_cfg_gre.value, (value ? CTC_LB_HASH_FIELD_GRE_KEY_LO : 0));
            CTC_SET_FLAG(hash_cfg_gre.value, (value ? CTC_LB_HASH_FIELD_GRE_KEY_HI : 0));
            value = CTC_FLAG_ISSET(p_psc->l4_flag, CTC_PARSER_L4_HASH_FLAGS_L4_NVGRE_VSID);
            CTC_SET_FLAG(hash_cfg_nvgre.value, (value ? CTC_LB_HASH_FIELD_VNI_LO : 0));
            CTC_SET_FLAG(hash_cfg_nvgre.value, (value ? CTC_LB_HASH_FIELD_VNI_HI : 0));
            use_template_gre = 1;
        }
        else
        {
            value = CTC_FLAG_ISSET(p_psc->l4_flag, CTC_PARSER_L4_HASH_FLAGS_SRC_PORT);
            CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_L4_SRCPORT : 0));

            value = CTC_FLAG_ISSET(p_psc->l4_flag, CTC_PARSER_L4_HASH_FLAGS_DST_PORT);
            CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_L4_DSTPORT : 0));

            value = CTC_FLAG_ISSET(p_psc->l4_flag, CTC_PARSER_L4_HASH_FLAGS_VXLAN_L4_SRC_PORT);
            CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_L4_SRCPORT : 0));

            value = CTC_FLAG_ISSET(p_psc->l4_flag, CTC_PARSER_L4_HASH_FLAGS_L4_VXLAN_VNI);
            CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_VNI_LO : 0));
            CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_VNI_HI : 0));
            use_template_ip = 1;
        }
    }

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_PORT);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_SRC_PORT : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_DST_PORT);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_DST_PORT : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_SRC_CHIP_ID);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_SRC_CHIP_ID : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_DST_CHIP_ID);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_DST_CHIP_ID : 0));
    
    if (use_template_gre)
    {
        hash_cfg_gre.hash_select = CTC_LB_HASH_SELECT_IPV4_GRE;
        CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg_gre));
        hash_cfg_nvgre.hash_select = CTC_LB_HASH_SELECT_IPV4_NVGRE;
        CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg_nvgre));
        hash_cfg_gre.hash_select = CTC_LB_HASH_SELECT_IPV6_GRE;
        CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg_gre));
        hash_cfg_nvgre.hash_select = CTC_LB_HASH_SELECT_IPV6_NVGRE;
        CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg_nvgre));
    }
    else if (use_template_ip)
    {
        for (i = 0; i < sizeof(template_ip) / 4; i++)
        {
            hash_cfg.hash_select = template_ip[i];
            CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
        }
    }
    if (l3_info_en)
    {
        if (use_template_ip == 0)
        {
            for (i = 0; i < sizeof(template_ip) / 4; i++)
            {
                hash_cfg.hash_select = template_ip[i];
                CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
            }
        }
        if (use_template_gre == 0)
        {
            hash_cfg_gre.hash_select = CTC_LB_HASH_SELECT_IPV4_GRE;
            CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg_gre));
            hash_cfg_nvgre.hash_select = CTC_LB_HASH_SELECT_IPV4_NVGRE;
            CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg_nvgre));
            hash_cfg_gre.hash_select = CTC_LB_HASH_SELECT_IPV6_GRE;
            CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg_gre));
            hash_cfg_nvgre.hash_select = CTC_LB_HASH_SELECT_IPV6_NVGRE;
            CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg_nvgre));
        }
    }
    hash_cfg.value = (CTC_FLAG_ISSET(p_psc->l4_flag, CTC_PARSER_L4_HASH_FLAGS_L4_NVGRE_VSID)) ? 1 : 0;
    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_CONTROL;
    hash_cfg.sel_id = hash_usage;
    hash_cfg.hash_control = CTC_LB_HASH_CONTROL_NVGRE_AWARE ;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    CTC_SET_FLAG(useless_flag,  CTC_PARSER_IP_HASH_FLAGS_DSCP);
    CTC_SET_FLAG(useless_flag,  CTC_PARSER_IP_HASH_FLAGS_ECN);
    if (CTC_FLAG_ISSET(p_psc->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_IP) && (p_psc->ip_flag & useless_flag))
    {
        CTC_UNSET_FLAG(p_psc->ip_flag, useless_flag);
        return CTC_E_PARTIAL_PARAM;
    }
    useless_flag = 0;
    CTC_SET_FLAG(useless_flag,  CTC_PARSER_L4_HASH_FLAGS_VXLAN_L4_DST_PORT);
    CTC_SET_FLAG(useless_flag,  CTC_PARSER_L4_HASH_FLAGS_L4_TYPE);
    CTC_SET_FLAG(useless_flag,  CTC_PARSER_L4_HASH_FLAGS_L4_USER_TYPE);
    CTC_SET_FLAG(useless_flag,  CTC_PARSER_L4_HASH_FLAGS_L4_TCP_FLAG);
    CTC_SET_FLAG(useless_flag,  CTC_PARSER_L4_HASH_FLAGS_L4_NVGRE_FLOW_ID);
    CTC_SET_FLAG(useless_flag,  CTC_PARSER_L4_HASH_FLAGS_L4_TCP_ECN);
    if (CTC_FLAG_ISSET(p_psc->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_L4) && (p_psc->l4_flag & useless_flag))
    {
        CTC_UNSET_FLAG(p_psc->l4_flag, useless_flag);
        return CTC_E_PARTIAL_PARAM;
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_parser_get_l3_l4_hash(uint8 lchip, ctc_parser_hash_ctl_t* p_psc,
                                sys_parser_hash_usage_t hash_usage)
{
    uint32 value = 0;
    ctc_lb_hash_config_t hash_cfg;

    uint32 bitmap = 0;
    sal_memset(&hash_cfg, 0, sizeof(hash_cfg));

    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_SELECT;
    hash_cfg.sel_id = hash_usage;


    hash_cfg.hash_select = CTC_LB_HASH_SELECT_IPV6;
    CTC_ERROR_RETURN(sys_tsingma_hash_get_config(lchip, &hash_cfg));
    bitmap = hash_cfg.value;

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_L4_SRCPORT);
    CTC_SET_FLAG(p_psc->l4_flag, (value ? CTC_PARSER_L4_HASH_FLAGS_SRC_PORT : 0));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_L4_DSTPORT);
    CTC_SET_FLAG(p_psc->l4_flag, (value ? CTC_PARSER_L4_HASH_FLAGS_DST_PORT : 0));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_L4_SRCPORT);
    CTC_SET_FLAG(p_psc->l4_flag, (value ? CTC_PARSER_L4_HASH_FLAGS_VXLAN_L4_SRC_PORT : 0));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_VNI_LO);
    CTC_SET_FLAG(p_psc->l4_flag, (value ? CTC_PARSER_L4_HASH_FLAGS_L4_VXLAN_VNI : 0));


    /**<gre,nvgre packets*/
    hash_cfg.hash_select = CTC_LB_HASH_SELECT_IPV4_GRE;
    CTC_ERROR_RETURN(sys_tsingma_hash_get_config(lchip, &hash_cfg));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_GRE_KEY_LO);
    value &= CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_GRE_KEY_HI);
    CTC_SET_FLAG(p_psc->l4_flag, (value ? CTC_PARSER_L4_HASH_FLAGS_GRE_KEY : 0));

    hash_cfg.hash_select = CTC_LB_HASH_SELECT_IPV4_NVGRE;
    CTC_ERROR_RETURN(sys_tsingma_hash_get_config(lchip, &hash_cfg));
    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_VNI_LO);
    CTC_SET_FLAG(p_psc->l4_flag, (value ? CTC_PARSER_L4_HASH_FLAGS_L4_NVGRE_VSID : 0));

   /* IPv4/IPv6*/
    hash_cfg.value |= bitmap;

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_PROTOCOL);
    CTC_SET_FLAG(p_psc->ip_flag, (value ? CTC_PARSER_IP_HASH_FLAGS_PROTOCOL : 0));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_FLOWLABEL_LO);
    CTC_SET_FLAG(p_psc->ip_flag, (value ? CTC_PARSER_IP_HASH_FLAGS_IPV6_FLOW_LABEL : 0));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_IP_SA_LO);
    CTC_SET_FLAG(p_psc->ip_flag, (value ? CTC_PARSER_IP_HASH_FLAGS_IPSA : 0));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_IP_DA_LO);
    CTC_SET_FLAG(p_psc->ip_flag, (value ? CTC_PARSER_IP_HASH_FLAGS_IPDA : 0));

    return CTC_E_NONE;
}


STATIC int32
_sys_tsingma_parser_set_mpls_hash(uint8 lchip, ctc_parser_hash_ctl_t* p_psc, sys_parser_hash_usage_t hash_usage)
{
    uint32 value = 0;
    ctc_lb_hash_config_t hash_cfg;

    sal_memset(&hash_cfg, 0, sizeof(hash_cfg));
    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_SELECT;
    hash_cfg.sel_id = hash_usage;
    /**<mpls packets*/

    value = CTC_FLAG_ISSET(p_psc->mpls_flag, CTC_PARSER_MPLS_HASH_FLAGS_PROTOCOL);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_PROTOCOL : 0));

    value = CTC_FLAG_ISSET(p_psc->mpls_flag, CTC_PARSER_MPLS_HASH_FLAGS_IPV6_FLOW_LABEL);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_FLOWLABEL_LO : 0));
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_FLOWLABEL_HI : 0));

    value = CTC_FLAG_ISSET(p_psc->mpls_flag, CTC_PARSER_MPLS_HASH_FLAGS_IPSA);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_IP_SA_LO : 0));
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_IP_SA_HI : 0));

    value = CTC_FLAG_ISSET(p_psc->mpls_flag, CTC_PARSER_MPLS_HASH_FLAGS_IPDA);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_IP_DA_LO : 0));
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_IP_DA_HI : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_PORT);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_SRC_PORT : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_DST_PORT);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_DST_PORT : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_SRC_CHIP_ID);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_SRC_CHIP_ID : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_DST_CHIP_ID);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_DST_CHIP_ID : 0));
    
    hash_cfg.hash_select = CTC_LB_HASH_SELECT_MPLS;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    hash_cfg.hash_select = CTC_LB_HASH_SELECT_MPLS_INNER_IPV4;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));

    hash_cfg.hash_select = CTC_LB_HASH_SELECT_MPLS_INNER_IPV6;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    hash_cfg.hash_select = CTC_LB_HASH_SELECT_MPLS_VPWS_RAW;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    hash_cfg.hash_select = CTC_LB_HASH_SELECT_MPLS_L2VPN_INNER_IPV4;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));

    hash_cfg.hash_select = CTC_LB_HASH_SELECT_MPLS_L2VPN_INNER_IPV6;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    hash_cfg.hash_select = CTC_LB_HASH_SELECT_MPLS_L3VPN_INNER_IPV4;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    hash_cfg.hash_select = CTC_LB_HASH_SELECT_MPLS_L3VPN_INNER_IPV6;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    if (CTC_FLAG_ISSET(p_psc->mpls_flag, CTC_PARSER_MPLS_HASH_FLAGS_DSCP)
       || CTC_FLAG_ISSET(p_psc->mpls_flag, CTC_PARSER_MPLS_HASH_FLAGS_CANCEL_LABEL))
    {
        CTC_UNSET_FLAG(p_psc->mpls_flag, CTC_PARSER_MPLS_HASH_FLAGS_DSCP);
        CTC_UNSET_FLAG(p_psc->mpls_flag, CTC_PARSER_MPLS_HASH_FLAGS_CANCEL_LABEL);
        return CTC_E_PARTIAL_PARAM;
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_parser_get_mpls_hash(uint8 lchip, ctc_parser_hash_ctl_t* p_psc, sys_parser_hash_usage_t hash_usage)
{
    uint32 value = 0;
    ctc_lb_hash_config_t hash_cfg;

    sal_memset(&hash_cfg, 0, sizeof(hash_cfg));
    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_SELECT;
    hash_cfg.sel_id = hash_usage;
    /**<mpls packets*/

    hash_cfg.hash_select = CTC_LB_HASH_SELECT_MPLS;
    CTC_ERROR_RETURN(sys_tsingma_hash_get_config(lchip, &hash_cfg));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_PROTOCOL);
    CTC_SET_FLAG(p_psc->mpls_flag, (value ? CTC_PARSER_MPLS_HASH_FLAGS_PROTOCOL : 0));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_FLOWLABEL_LO);
    value &= CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_FLOWLABEL_HI);
    CTC_SET_FLAG(p_psc->mpls_flag, (value ? CTC_PARSER_MPLS_HASH_FLAGS_IPV6_FLOW_LABEL : 0));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_IP_SA_LO);
    value &= CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_IP_SA_HI);
    CTC_SET_FLAG(p_psc->mpls_flag, (value ? CTC_PARSER_MPLS_HASH_FLAGS_IPSA : 0));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_IP_DA_LO);
    value &= CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_IP_DA_HI);
    CTC_SET_FLAG(p_psc->mpls_flag, (value ? CTC_PARSER_MPLS_HASH_FLAGS_IPDA : 0));

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_parser_set_trill_hash(uint8 lchip, ctc_parser_hash_ctl_t* p_psc, sys_parser_hash_usage_t hash_usage)
{
    uint32 value = 0;
    ctc_lb_hash_config_t hash_cfg;

    sal_memset(&hash_cfg, 0, sizeof(hash_cfg));
    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_SELECT;
    hash_cfg.sel_id = hash_usage;
    /**<TRILL packets*/

    value = CTC_FLAG_ISSET(p_psc->trill_flag, CTC_PARSER_TRILL_HASH_FLAGS_INNER_VLAN_ID);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_SVLAN : 0));

    value = CTC_FLAG_ISSET(p_psc->trill_flag, CTC_PARSER_TRILL_HASH_FLAGS_INGRESS_NICKNAME);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_INGRESS_NICKNAME : 0));

    value = CTC_FLAG_ISSET(p_psc->trill_flag, CTC_PARSER_TRILL_HASH_FLAGS_EGRESS_NICKNAME);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_EGRESS_NICKNAME : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_PORT);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_SRC_PORT : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_DST_PORT);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_DST_PORT : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_SRC_CHIP_ID);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_SRC_CHIP_ID : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_DST_CHIP_ID);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_DST_CHIP_ID : 0));

    hash_cfg.hash_select = CTC_LB_HASH_SELECT_TRILL;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));

    hash_cfg.hash_select = CTC_LB_HASH_SELECT_TRILL_INNER_L2;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_parser_get_trill_hash(uint8 lchip, ctc_parser_hash_ctl_t* p_psc, sys_parser_hash_usage_t hash_usage)
{
    uint32 value = 0;
    ctc_lb_hash_config_t hash_cfg;

    sal_memset(&hash_cfg, 0, sizeof(hash_cfg));
    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_SELECT;
    hash_cfg.sel_id = hash_usage;
    /**<TRILL packets*/

    hash_cfg.hash_select = CTC_LB_HASH_SELECT_TRILL;
    CTC_ERROR_RETURN(sys_tsingma_hash_get_config(lchip, &hash_cfg));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_SVLAN);
    CTC_SET_FLAG(p_psc->trill_flag, (value ? CTC_PARSER_TRILL_HASH_FLAGS_INNER_VLAN_ID : 0));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_INGRESS_NICKNAME);
    CTC_SET_FLAG(p_psc->trill_flag, (value ? CTC_PARSER_TRILL_HASH_FLAGS_INGRESS_NICKNAME : 0));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_EGRESS_NICKNAME);
    CTC_SET_FLAG(p_psc->trill_flag, (value ? CTC_PARSER_TRILL_HASH_FLAGS_EGRESS_NICKNAME : 0));
    return CTC_E_NONE;
}


STATIC int32
_sys_tsingma_parser_set_fcoe_hash(uint8 lchip, ctc_parser_hash_ctl_t* p_psc,
                                  sys_parser_hash_usage_t hash_usage)
{
    uint32 value = 0;
    ctc_lb_hash_config_t hash_cfg;

    sal_memset(&hash_cfg, 0, sizeof(hash_cfg));

    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_SELECT;
    hash_cfg.sel_id = hash_usage;
    /**<FCOE packets*/

    value = CTC_FLAG_ISSET(p_psc->fcoe_flag, CTC_PARSER_FCOE_HASH_FLAGS_SID);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_FCOE_SID_LO : 0));
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_FCOE_SID_HI : 0));


    value = CTC_FLAG_ISSET(p_psc->fcoe_flag, CTC_PARSER_FCOE_HASH_FLAGS_DID);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_FCOE_DID_LO : 0));
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_FCOE_DID_HI : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_PORT);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_SRC_PORT : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_DST_PORT);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_DST_PORT : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_SRC_CHIP_ID);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_SRC_CHIP_ID : 0));

    value = CTC_FLAG_ISSET(p_psc->l2_flag,  CTC_PARSER_L2_HASH_FLAGS_DST_CHIP_ID);
    CTC_SET_FLAG(hash_cfg.value, (value ? CTC_LB_HASH_FIELD_DST_CHIP_ID : 0));
    
    hash_cfg.hash_select = CTC_LB_HASH_SELECT_FCOE;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_parser_get_fcoe_hash(uint8 lchip, ctc_parser_hash_ctl_t* p_psc,
                                  sys_parser_hash_usage_t hash_usage)
{
    uint32 value = 0;
    ctc_lb_hash_config_t hash_cfg;

    sal_memset(&hash_cfg, 0, sizeof(hash_cfg));

    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_SELECT;
    hash_cfg.sel_id = hash_usage;
    /**<FCOE packets*/

    hash_cfg.hash_select = CTC_LB_HASH_SELECT_FCOE;
    CTC_ERROR_RETURN(sys_tsingma_hash_get_config(lchip, &hash_cfg));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_FCOE_SID_LO);
    value &= CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_FCOE_SID_HI);
    CTC_SET_FLAG(p_psc->fcoe_flag, (value ? CTC_PARSER_FCOE_HASH_FLAGS_SID : 0));

    value = CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_FCOE_DID_LO);
    value &= CTC_FLAG_ISSET(hash_cfg.value, CTC_LB_HASH_FIELD_FCOE_DID_HI);
    CTC_SET_FLAG(p_psc->fcoe_flag, (value ? CTC_PARSER_FCOE_HASH_FLAGS_DID : 0));
    return CTC_E_NONE;
}




int32
sys_tsingma_parser_set_hash_field(uint8 lchip, void* p_ctl, uint8 usage)
{
    ctc_lb_hash_config_t hash_cfg;
    ctc_parser_hash_ctl_t* p_hash_ctl = (ctc_parser_hash_ctl_t*)p_ctl;
    sys_parser_hash_usage_t hash_usage = (sys_parser_hash_usage_t)usage;

    CTC_PTR_VALID_CHECK(p_hash_ctl);
    if ((CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap , CTC_PARSER_HASH_TYPE_FLAGS_INNER))
        && (CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap , CTC_PARSER_HASH_TYPE_FLAGS_L2_ONLY)))
    {
        return CTC_E_PARAM_CONFLICT;
    }
    SYS_PARSER_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PARSER_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "hash_type_bitmap:%d\n", p_hash_ctl->hash_type_bitmap);

    sal_memset(&hash_cfg, 0, sizeof(hash_cfg));

    /*CTC_PARSER_HASH_TYPE_FLAGS_L2_ONLY*/
    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_CONTROL;
    hash_cfg.sel_id = hash_usage;
    hash_cfg.hash_control = CTC_LB_HASH_CONTROL_L2_ONLY;
    if (CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_L2_ONLY)||
        p_hash_ctl->hash_type_bitmap == CTC_PARSER_HASH_TYPE_FLAGS_L2 ||
        p_hash_ctl->hash_type_bitmap == (CTC_PARSER_HASH_TYPE_FLAGS_L2 | CTC_PARSER_HASH_TYPE_FLAGS_INNER) ||
    p_hash_ctl->hash_type_bitmap == (CTC_PARSER_HASH_TYPE_FLAGS_L2 | CTC_PARSER_HASH_TYPE_FLAGS_DLB_EFD) ||
    p_hash_ctl->hash_type_bitmap == (CTC_PARSER_HASH_TYPE_FLAGS_L2 | CTC_PARSER_HASH_TYPE_FLAGS_DLB))
    {
        hash_cfg.value = 1;
    }
    else
    {
        hash_cfg.value = 0;
    }
    hash_cfg.value = CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap , CTC_PARSER_HASH_TYPE_FLAGS_INNER) ? 0: hash_cfg.value;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));

    /* CTC_PARSER_HASH_TYPE_FLAGS */
    if (CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_L2))
    {
        CTC_ERROR_RETURN(_sys_tsingma_parser_set_layer2_hash(lchip, p_hash_ctl, hash_usage));
    }

    if (CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_IP) ||
        CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_L4) )
    {
        CTC_ERROR_RETURN(_sys_tsingma_parser_set_l3_l4_hash(lchip, p_hash_ctl, hash_usage));
    }

    if (CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_MPLS))
    {
        CTC_ERROR_RETURN(_sys_tsingma_parser_set_mpls_hash(lchip, p_hash_ctl, hash_usage));
    }

    if (CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_TRILL))
    {
        CTC_ERROR_RETURN(_sys_tsingma_parser_set_trill_hash(lchip, p_hash_ctl, hash_usage));
    }

    if (CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_FCOE))
    {
        CTC_ERROR_RETURN(_sys_tsingma_parser_set_fcoe_hash(lchip, p_hash_ctl, hash_usage));
    }

    /*CTC_PARSER_HASH_TYPE_FLAGS_INNER*/
    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_CONTROL;
    hash_cfg.sel_id = hash_usage;
    hash_cfg.hash_control = CTC_LB_HASH_CONTROL_L2VPN_USE_INNER_L2 ;
    hash_cfg.value = (CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap , CTC_PARSER_HASH_TYPE_FLAGS_INNER) && CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_L2) )? 1:0;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_CONTROL;
    hash_cfg.sel_id = hash_usage;
    hash_cfg.hash_control = CTC_LB_HASH_CONTROL_VPWS_USE_INNER ;
    hash_cfg.value = (CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_INNER))? 1:0;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_CONTROL;
    hash_cfg.sel_id = hash_usage;
    hash_cfg.hash_control = CTC_LB_HASH_CONTROL_TRILL_DECAP_USE_INNER_L2 ;
    hash_cfg.value = (CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap ,CTC_PARSER_HASH_TYPE_FLAGS_INNER)  && CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_L2))? 1:0;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_CONTROL;
    hash_cfg.sel_id = hash_usage;
    hash_cfg.hash_control = CTC_LB_HASH_CONTROL_VXLAN_USE_INNER_L2 ;
    hash_cfg.value = (CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap , CTC_PARSER_HASH_TYPE_FLAGS_INNER) && CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_L2))? 1:0;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_CONTROL;
    hash_cfg.sel_id = hash_usage;
    hash_cfg.hash_control = CTC_LB_HASH_CONTROL_NVGRE_USE_INNER_L2 ;
    hash_cfg.value = (CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_INNER) && CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_L2))? 1:0;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_CONTROL;
    hash_cfg.sel_id = hash_usage;
    hash_cfg.hash_control = CTC_LB_HASH_CONTROL_FLEX_TNL_USE_INNER_L2 ;
    hash_cfg.value = (CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap ,CTC_PARSER_HASH_TYPE_FLAGS_INNER) && CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_L2))? 1:0;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    if (p_hash_ctl->udf_id || p_hash_ctl->udf_bitmap || p_hash_ctl->pbb_flag ||p_hash_ctl->common_flag)
    {
        p_hash_ctl->udf_id = 0;
        p_hash_ctl->udf_bitmap = 0;
        p_hash_ctl->pbb_flag = 0;
        p_hash_ctl->common_flag = 0;
        return CTC_E_PARTIAL_PARAM;
    }
    return CTC_E_NONE;
}

int32
sys_tsingma_parser_get_hash_field(uint8 lchip,
                                  ctc_parser_hash_ctl_t* p_hash_ctl,
                                  sys_parser_hash_usage_t hash_usage)
{

    ctc_lb_hash_config_t hash_cfg;
    CTC_PTR_VALID_CHECK(p_hash_ctl);
    SYS_PARSER_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PARSER_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "hash_type_bitmap:%d\n", p_hash_ctl->hash_type_bitmap);

    if (CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_L2))
    {
        CTC_ERROR_RETURN(_sys_tsingma_parser_get_layer2_hash(lchip, p_hash_ctl, hash_usage));
    }

    if (CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_IP) ||
        CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_L4) )
    {
        CTC_ERROR_RETURN(_sys_tsingma_parser_get_l3_l4_hash(lchip, p_hash_ctl, hash_usage));
    }

    if (CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_MPLS))
    {
        CTC_ERROR_RETURN(_sys_tsingma_parser_get_mpls_hash(lchip, p_hash_ctl, hash_usage));
    }

    if (CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_TRILL))
    {
        CTC_ERROR_RETURN(_sys_tsingma_parser_get_trill_hash(lchip, p_hash_ctl, hash_usage));
    }

    if (CTC_FLAG_ISSET(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_FCOE))
    {
        CTC_ERROR_RETURN(_sys_tsingma_parser_get_fcoe_hash(lchip, p_hash_ctl, hash_usage));
    }
    /*CTC_PARSER_HASH_TYPE_FLAGS_L2_ONLY*/
    sal_memset(&hash_cfg, 0, sizeof(ctc_lb_hash_config_t));
    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_CONTROL;
    hash_cfg.sel_id = hash_usage;
    hash_cfg.hash_control = CTC_LB_HASH_CONTROL_L2_ONLY;
    CTC_ERROR_RETURN(sys_tsingma_hash_get_config(lchip, &hash_cfg));
    if (hash_cfg.value == 1)
    {
        CTC_SET_FLAG(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_L2_ONLY);
    }
    /*CTC_PARSER_HASH_TYPE_FLAGS_INNER*/
    sal_memset(&hash_cfg, 0, sizeof(ctc_lb_hash_config_t));
    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_CONTROL;
    hash_cfg.sel_id = hash_usage;
    hash_cfg.hash_control = CTC_LB_HASH_CONTROL_VPWS_USE_INNER ;
    CTC_ERROR_RETURN(sys_tsingma_hash_get_config(lchip, &hash_cfg));
    if (hash_cfg.value == 1)
    {
        CTC_SET_FLAG(p_hash_ctl->hash_type_bitmap, CTC_PARSER_HASH_TYPE_FLAGS_INNER);
    }
    return CTC_E_NONE;
}

extern int32
sys_tsingma_parser_set_global_cfg(uint8 lchip, ctc_parser_global_cfg_t* p_global_cfg)
{
    uint32 cmd = 0;
    uint8 index = 0;
    ctc_lb_hash_config_t hash_cfg;
    ParserIpCtl_m ip_ctl;

    CTC_PTR_VALID_CHECK(p_global_cfg);
    CTC_MAX_VALUE_CHECK(p_global_cfg->small_frag_offset, 3);
    sal_memset(&hash_cfg, 0, sizeof(ctc_lb_hash_config_t));
    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_CONTROL;
    hash_cfg.sel_id = SYS_PARSER_HASH_USAGE_ECMP;
    hash_cfg.hash_control = CTC_LB_HASH_CONTROL_HASH_TYPE_A ;
    hash_cfg.value = (CTC_PARSER_GEN_HASH_TYPE_XOR == p_global_cfg->ecmp_hash_type) ? CTC_LB_HASH_TYPE_XOR8 : CTC_LB_HASH_TYPE_CRC8_POLY1;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    if(MCHIP_CAP(SYS_CAP_LB_HASH_SELECT_NUM) == SYS_USW_LB_HASH_CTL_NUM)
    {
        hash_cfg.hash_control = CTC_LB_HASH_CONTROL_HASH_TYPE_B ;
        hash_cfg.value = (CTC_PARSER_GEN_HASH_TYPE_XOR == p_global_cfg->ecmp_hash_type) ?  CTC_LB_HASH_TYPE_CRC8_POLY1 :CTC_LB_HASH_TYPE_XOR8;
        CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    }
    sal_memset(&hash_cfg, 0, sizeof(ctc_lb_hash_config_t));
    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_CONTROL;
    hash_cfg.sel_id = SYS_PARSER_HASH_USAGE_LINKAGG;
    hash_cfg.hash_control = CTC_LB_HASH_CONTROL_HASH_TYPE_A ;
    hash_cfg.value = (CTC_PARSER_GEN_HASH_TYPE_XOR == p_global_cfg->linkagg_hash_type) ? CTC_LB_HASH_TYPE_XOR8 : CTC_LB_HASH_TYPE_CRC8_POLY1;
    CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    if(MCHIP_CAP(SYS_CAP_LB_HASH_SELECT_NUM) == SYS_USW_LB_HASH_CTL_NUM)
    {
        hash_cfg.hash_control = CTC_LB_HASH_CONTROL_HASH_TYPE_B ;
        hash_cfg.value = (CTC_PARSER_GEN_HASH_TYPE_XOR == p_global_cfg->ecmp_hash_type) ?  CTC_LB_HASH_TYPE_CRC8_POLY1 :CTC_LB_HASH_TYPE_XOR8;
        CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    }

    sal_memset(&ip_ctl, 0, sizeof(ip_ctl));
    cmd = DRV_IOR(ParserIpCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ip_ctl));
    SetParserIpCtl(V, smallFragmentOffset_f, &ip_ctl, p_global_cfg->small_frag_offset);
    cmd = DRV_IOW(ParserIpCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ip_ctl));

    sal_memset(&hash_cfg, 0, sizeof(ctc_lb_hash_config_t));
    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_CONTROL;
    hash_cfg.value = p_global_cfg->symmetric_hash_en;
    for(index = 0; index < MCHIP_CAP(SYS_CAP_LB_HASH_SELECT_NUM); index++)
    {
        hash_cfg.sel_id = index;
        hash_cfg.hash_control = CTC_LB_HASH_CONTROL_IPV4_SYMMETRIC_EN ;
        CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));

        hash_cfg.hash_control = CTC_LB_HASH_CONTROL_IPV6_SYMMETRIC_EN ;
        CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));

        hash_cfg.hash_control = CTC_LB_HASH_CONTROL_FCOE_SYMMETRIC_EN ;
        CTC_ERROR_RETURN(sys_tsingma_hash_set_config(lchip, &hash_cfg));
    }

    return CTC_E_NONE;
}

extern int32
sys_tsingma_parser_get_global_cfg(uint8 lchip, ctc_parser_global_cfg_t* p_global_cfg)
{
    uint32 cmd = 0;
    uint8 index = 0;
    uint8 value = 1;
    ctc_lb_hash_config_t hash_cfg;
    ParserIpCtl_m ip_ctl;

    CTC_PTR_VALID_CHECK(p_global_cfg);
    sal_memset(&hash_cfg, 0, sizeof(ctc_lb_hash_config_t));
    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_CONTROL;
    hash_cfg.sel_id = SYS_PARSER_HASH_USAGE_ECMP;
    hash_cfg.hash_control = CTC_LB_HASH_CONTROL_HASH_TYPE_A ;
    CTC_ERROR_RETURN(sys_tsingma_hash_get_config(lchip, &hash_cfg));
    p_global_cfg->ecmp_hash_type =  (hash_cfg.value == CTC_LB_HASH_TYPE_XOR8) ? CTC_PARSER_GEN_HASH_TYPE_XOR : CTC_PARSER_GEN_HASH_TYPE_CRC;
    sal_memset(&hash_cfg, 0, sizeof(ctc_lb_hash_config_t));
    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_CONTROL;
    hash_cfg.sel_id = SYS_PARSER_HASH_USAGE_LINKAGG;
    hash_cfg.hash_control = CTC_LB_HASH_CONTROL_HASH_TYPE_A ;
    CTC_ERROR_RETURN(sys_tsingma_hash_get_config(lchip, &hash_cfg));
    p_global_cfg->linkagg_hash_type =  (hash_cfg.value == CTC_LB_HASH_TYPE_XOR8) ? CTC_PARSER_GEN_HASH_TYPE_XOR : CTC_PARSER_GEN_HASH_TYPE_CRC;

    sal_memset(&ip_ctl, 0, sizeof(ip_ctl));
    cmd = DRV_IOR(ParserIpCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ip_ctl));
    p_global_cfg->small_frag_offset = GetParserIpCtl(V, smallFragmentOffset_f, &ip_ctl);

    sal_memset(&hash_cfg, 0, sizeof(ctc_lb_hash_config_t));
    hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_CONTROL;
    for(index = 0; index < MCHIP_CAP(SYS_CAP_LB_HASH_SELECT_NUM); index++)
    {
        hash_cfg.sel_id = index;
        hash_cfg.hash_control = CTC_LB_HASH_CONTROL_IPV4_SYMMETRIC_EN ;
        CTC_ERROR_RETURN(sys_tsingma_hash_get_config(lchip, &hash_cfg));
        value &= hash_cfg.value;

        hash_cfg.hash_control = CTC_LB_HASH_CONTROL_IPV6_SYMMETRIC_EN ;
        CTC_ERROR_RETURN(sys_tsingma_hash_get_config(lchip, &hash_cfg));
        value &= hash_cfg.value;

        hash_cfg.hash_control = CTC_LB_HASH_CONTROL_FCOE_SYMMETRIC_EN ;
        CTC_ERROR_RETURN(sys_tsingma_hash_get_config(lchip, &hash_cfg));
        value &= hash_cfg.value;
    }
    p_global_cfg->symmetric_hash_en = value;
    return CTC_E_NONE;
}


int32
sys_tsingma_lb_hash_show_hash_cfg(uint8 lchip,ctc_lb_hash_config_t hash_cfg)
{
    uint16 hash_select = 0;
    uint16 hash_control = 0;
    uint8 tmplate = 0;
    uint8 loop = 0;
    ctc_lb_hash_config_t hash_cfg1;
    char* hash_sel_str[] = {SYS_LB_HASH_SEL_STR};
    char* hash_ctl_str[] = {SYS_LB_HASH_CTL_STR};
	SYS_LB_HASH_INIT_CHECK();

    sal_memset(&hash_cfg1,0,sizeof(ctc_lb_hash_config_t));
    hash_cfg1.sel_id = hash_cfg.sel_id;
    hash_cfg1.cfg_type= hash_cfg.cfg_type;
    CTC_MAX_VALUE_CHECK(hash_cfg1.sel_id,MCHIP_CAP(SYS_CAP_LB_HASH_SELECT_NUM)-1);    
     /*if (DRV_IS_DUET2(lchip))*/
    {
      /*   return CTC_E_NOT_SUPPORT;*/
    }

    /*show hash select tempmlate*/

    /*show hash select value*/
    if (hash_cfg1.cfg_type == CTC_LB_HASH_CFG_HASH_SELECT)
    {
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\nNo. %-30s%-15s%-20s\n", "hash-select", "value", "template");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s\n", "======================================================");
        for (hash_select = CTC_LB_HASH_SELECT_L2; hash_select < CTC_LB_HASH_SELECT_MAX; hash_select++)
        {
            switch(hash_select)
            {
            case CTC_LB_HASH_SELECT_L2:
            case CTC_LB_HASH_SELECT_NVGRE_INNER_L2:
            case CTC_LB_HASH_SELECT_VXLAN_INNER_L2:
            case CTC_LB_HASH_SELECT_MPLS_L2VPN_INNER_L2:
            case CTC_LB_HASH_SELECT_TRILL_OUTER_L2_ONLY:
            case CTC_LB_HASH_SELECT_TRILL_DECAP_INNER_L2:
            case CTC_LB_HASH_SELECT_FLEX_TNL_INNER_L2:
                tmplate = 0;
                break;
            case CTC_LB_HASH_SELECT_TRILL:
            case CTC_LB_HASH_SELECT_TRILL_INNER_L2:
                tmplate = 1;
                break;
            case CTC_LB_HASH_SELECT_FCOE:
                tmplate = 2;
                break;
            case CTC_LB_HASH_SELECT_MPLS:
            case CTC_LB_HASH_SELECT_MPLS_INNER_IPV4:
            case CTC_LB_HASH_SELECT_MPLS_INNER_IPV6:
            case CTC_LB_HASH_SELECT_MPLS_VPWS_RAW:
                tmplate = 3;
                break;
            case CTC_LB_HASH_SELECT_IPV4:
            case CTC_LB_HASH_SELECT_IPV4_TCP_UDP:
            case CTC_LB_HASH_SELECT_IPV4_TCP_UDP_PORTS_EQUAL:
            case CTC_LB_HASH_SELECT_IPV4_VXLAN:
            case CTC_LB_HASH_SELECT_IPV6:
            case CTC_LB_HASH_SELECT_IPV6_TCP_UDP:
            case CTC_LB_HASH_SELECT_IPV6_TCP_UDP_PORTS_EQUAL:
            case CTC_LB_HASH_SELECT_IPV6_VXLAN:
            case CTC_LB_HASH_SELECT_NVGRE_INNER_IPV4:
            case CTC_LB_HASH_SELECT_NVGRE_INNER_IPV6:
            case CTC_LB_HASH_SELECT_VXLAN_INNER_IPV4:
            case CTC_LB_HASH_SELECT_VXLAN_INNER_IPV6:
            case CTC_LB_HASH_SELECT_MPLS_L2VPN_INNER_IPV4:
            case CTC_LB_HASH_SELECT_MPLS_L2VPN_INNER_IPV6:
            case CTC_LB_HASH_SELECT_MPLS_L3VPN_INNER_IPV4:
            case CTC_LB_HASH_SELECT_MPLS_L3VPN_INNER_IPV6:
            case CTC_LB_HASH_SELECT_TRILL_INNER_IPV4:
            case CTC_LB_HASH_SELECT_TRILL_INNER_IPV6:
            case CTC_LB_HASH_SELECT_TRILL_DECAP_INNER_IPV4:
            case CTC_LB_HASH_SELECT_TRILL_DECAP_INNER_IPV6:
            case CTC_LB_HASH_SELECT_FLEX_TNL_INNER_IPV4:
            case CTC_LB_HASH_SELECT_FLEX_TNL_INNER_IPV6:
                tmplate = 4;
                break;

            case CTC_LB_HASH_SELECT_IPV4_GRE:
            case CTC_LB_HASH_SELECT_IPV4_NVGRE:
            case CTC_LB_HASH_SELECT_IPV6_GRE:
            case CTC_LB_HASH_SELECT_IPV6_NVGRE:
                tmplate = 5;
                break;

            case CTC_LB_HASH_SELECT_UDF:
                tmplate = 6;
                break;

            }
            hash_cfg1.cfg_type = CTC_LB_HASH_CFG_HASH_SELECT;
            hash_cfg1.hash_select = hash_select;
            if(hash_select == CTC_LB_HASH_SELECT_UDF)
            {
                /*udf porfile*/
                for (loop = 1; loop < SYS_LB_HASH_SCL_PROFILE_NUM; loop++)
                {
                    SYS_LB_HASH_ENCODE_SEL_ID(hash_cfg1.sel_id, hash_cfg.sel_id, loop);
                    CTC_ERROR_RETURN(sys_tsingma_hash_get_config(lchip, &hash_cfg1));
                    SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-3d %s%-27d 0x%04x          %d\n", hash_select, hash_sel_str[hash_select], loop, hash_cfg1.value, tmplate);
                }
                hash_cfg1.sel_id = hash_cfg.sel_id;
            }
            else
            {
                CTC_ERROR_RETURN(sys_tsingma_hash_get_config(lchip, &hash_cfg1));
                SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-3d %-30s 0x%04x          %d\n", hash_select, hash_sel_str[hash_select], hash_cfg1.value, tmplate);
            }
        }
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s\n", "======================================================");
    }
    /*show hash control value*/
    if (hash_cfg1.cfg_type == CTC_LB_HASH_CFG_HASH_CONTROL)
    {
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\nNo. %-28s %-20s\n", "hash-control", "value");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s\n", "========================================");
        for (hash_control = CTC_LB_HASH_CONTROL_L2_ONLY; hash_control < CTC_LB_HASH_CONTROL_MAX; hash_control++)
        {
            hash_cfg1.hash_control = hash_control;
            CTC_ERROR_RETURN(sys_tsingma_hash_get_config(lchip, &hash_cfg1));
            if(hash_control == CTC_LB_HASH_CONTROL_HASH_TYPE_UDF_DATA_BIT_MASK)
            {
                uint8 loop = 0;
                SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-3d %-30s:", hash_control, hash_ctl_str[hash_control]);
                for (loop = 0; loop < CTC_LB_HASH_UDF_BYTE_NUM; loop++)
                {
                    SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%02x", hash_cfg1.udf_mask[CTC_LB_HASH_UDF_BYTE_NUM - 1 - loop]);
                }
                SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");
            }
            else
            {
                SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-3d %-30s:%x\n", hash_control, hash_ctl_str[hash_control], hash_cfg1.value);
            }
        }
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s\n", "========================================");
    }
return 0;
}

int32
sys_tsingma_lb_hash_show_template(uint8 lchip,uint8 template_id)
{
    if (DRV_IS_DUET2(lchip))
    {
        return CTC_E_NOT_SUPPORT;
    }

    switch(template_id)
    {
    case 0:
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s:\n", "templet0");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------\n");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "", "", "", "Cvid");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "Svid", "EtherType", "MacDaHig", "MacDamid");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "MacDaLow", "MacSaHig", "MacSamid", "MacSaLow");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "DstChipId", "Dstlocalport", "Srcchipid", "Srclocalport");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------\n");
        break;
    case 1:
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s:\n", "templet1");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------\n");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "", "", "EgressNickname", "IngressNickname");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "Svid", "EtherType", "MacDaHig", "MacDamid");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "MacDaLow", "MacSaHig", "MacSamid", "MacSaLow");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "DstChipId", "Dstlocalport", "Srcchipid", "Srclocalport");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------\n");
        break;
    case 2:

        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s:\n", "templet2");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------\n");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "", "", "", "");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "", "", "UdfHigh", "UdfLow");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "FcoeDidHigh", "FcoeDidLow", "FcoeSidHigh", "FcoeSidLow");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "DstChipId", "Dstlocalport", "Srcchipid", "Srclocalport");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------\n");
        break;
    case 3:
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s:\n", "templet3");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------\n");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "", "", "MplsLabel2High", "MplsLabel1High");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "IpDaHigh", "IpDaLow", "IpSaHigh", "IpSaLow");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "MplsLabel0High", "MplsLabel2Low", "MplsLabel1Low", "MplsLabel0Low");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "DstChipId", "Dstlocalport", "Srcchipid", "Srclocalport");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------\n");
        break;
    case 4:
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s:\n", "templet4");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------\n");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "", "", "Udf/Ipv6FlowLabel", "Udf/Ipv6Label");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "Svid", "L4Info2", "L4Info1", "L4Protocol");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "IpDaHigh", "LpDaLow", "IpSaHig", "IpSaLow");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "DstChipId", "Dstlocalport", "Srcchipid", "Srclocalport");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------\n");
        break;
    case 5:
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s:\n", "templet5");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------\n");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "", "", "UdfHigh", "UdfLow");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "Svid", "GreKeyHigh", "GreKeyLow", "GreProType");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "IpDaHigh", "IpDaLow", "IpSaHigh", "IpSaLow");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "DstChipId", "Dstlocalport", "Srcchipid", "Srclocalport");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------\n");
        break;

    case 6:
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s:\n", "templet6");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------\n");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "", "", "", "");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "Udf[127:112]", "Udf[111:96]", "Udf[95:80]", "Udf[79:64]");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "Udf[63:48]", "Udf[47:32]", "Udf[31:16]", "Udf[15:0]");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "|%15s|%15s|%15s|%15s|\n", "DstChipId", "Dstlocalport", "Srcchipid", "Srclocalport");
        SYS_LB_HASH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------------------\n");
        break;

    default:
        return CTC_E_INVALID_PARAM;
    }
    return CTC_E_NONE;
}

int32
_sys_tsingma_hash_init(uint8 lchip)
{
    IpeHashCtl0_m hash_ctl;
    IpeEcmpCtl_m ecmp_ctl;
    uint32 cmd = 0;
    uint8 i = 0;
    uint8 gchip = 0;
    
    sys_usw_get_gchip_id(lchip, &gchip);
    for (i = 0; i < SYS_USW_LB_HASH_CTL_NUM * 2; i++)
    {
        sal_memset(&hash_ctl, 0, sizeof(hash_ctl));
        cmd = DRV_IOR(IpeHashCtl0_t + i, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hash_ctl));

        SetIpeHashCtl0(V, forceL2VpnMplsHashEn_f, &hash_ctl, 0);
        SetIpeHashCtl0(V, forceL3VpnMplsHashEn_f, &hash_ctl, 0);
        SetIpeHashCtl0(V, forceMplsHashEn_f, &hash_ctl, 1);
        SetIpeHashCtl0(V, hashSeedMask_f, &hash_ctl, 0x3);
        SetIpeHashCtl0(V, trillTerminateNodeHashMode_f, &hash_ctl, 1);
        SetIpeHashCtl0(V, trillTransitNodeHashMode_f, &hash_ctl, 3);
        SetIpeHashCtl0(V, ipv4EnableInnerHashTunnelBitmap_f, &hash_ctl, 0x3F);
        SetIpeHashCtl0(V, ipv6EnableInnerHashTunnelBitmap_f, &hash_ctl, 0x3F);
        SetIpeHashCtl0(V, transitNodeV4TunnelFormatPktHashMode_f, &hash_ctl, 0x3F);
        SetIpeHashCtl0(V, transitNodeV6TunnelFormatPktHashMode_f, &hash_ctl, 0x3F);
        SetIpeHashCtl0(V, ipv4NvgreInnerL3Bulk9And10UseVsiId_f, &hash_ctl, 1);/*tm*/
        SetIpeHashCtl0(V, ipv4NvgreInnerL3Bulk12And13UseVsiId_f, &hash_ctl, 1);/*tmm*/
        SetIpeHashCtl0(V, ipv4VxlanInnerL3Bulk12Andl3UseVni_f, &hash_ctl, 1);
        SetIpeHashCtl0(V, ipv6NvgreInnerL3Bulk9And10UseVsiId_f, &hash_ctl, 1);/*tm*/
        SetIpeHashCtl0(V, ipv6NvgreInnerL3Bulk12And13UseVsiId_f, &hash_ctl, 1);/*tmm*/
        SetIpeHashCtl0(V, ipv6VxlanInnerL3Bulk12Andl3UseVni_f, &hash_ctl, 1);
        SetIpeHashCtl0(V, mplsReservedLabel_f, &hash_ctl, 15);
        SetIpeHashCtl0(V, symmetricHashIpv4VxlanMaskL4Info_f, &hash_ctl, 1);
        SetIpeHashCtl0(V, symmetricHashIpv6VxlanMaskL4Info_f, &hash_ctl, 1);
        SetIpeHashCtl0(V, v4VxlanOuterL3HashUdfFieldUseVni_f, &hash_ctl, 1);
        SetIpeHashCtl0(V, v6VxlanOuterL3HashUdfFieldUseVni_f, &hash_ctl, 1);
        SetIpeHashCtl0(V, vxlanInnerL2HashUseVni_f, &hash_ctl, 1);
        SetIpeHashCtl0(V, nvgreInnerL2HashUseVsid_f, &hash_ctl, 1);
        SetIpeHashCtl0(V, hashSeed_f, &hash_ctl, gchip);
        cmd = DRV_IOW(IpeHashCtl0_t + i, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hash_ctl));
    }

    cmd = DRV_IOR(IpeEcmpCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ecmp_ctl));
    SetIpeEcmpCtl(V, hashOffsetForLoopEcmp_f, &ecmp_ctl, 0);
    SetIpeEcmpCtl(V, hashSelectForLoopEcmp_f, &ecmp_ctl, 8); /*vxlan ecmp loop use header ecmphash*/
    SetIpeEcmpCtl(V, gLevel1_hashOffsetForLoopEcmp_f, &ecmp_ctl, 0);
    SetIpeEcmpCtl(V, gLevel1_hashSelectForLoopEcmp_f, &ecmp_ctl, 8);
    cmd = DRV_IOW(IpeEcmpCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ecmp_ctl));

    /* hash init from AT */
    if (MCHIP_HASH(lchip)->hash_init)
    {
        MCHIP_HASH(lchip)->hash_init(lchip);
    }

    return CTC_E_NONE;
}

int32
sys_tsingma_parser_hash_init(uint8 lchip)
{
    uint8 hash_usage = 0;
    uint8 index = 0;
    ctc_parser_hash_ctl_t hash_ctl;
    ctc_lb_hash_config_t hash_cfg;
    ctc_lb_hash_offset_t p_hash_offset;
    uint8 lb_hash_mode = 0;
    uint16 lb_hash_offset = 0;

    lb_hash_mode = (MCHIP_CAP(SYS_CAP_LB_HASH_SELECT_NUM) == SYS_USW_LB_HASH_CTL_NUM)?0:1; /*4: old mode 8: new mode*/
    lb_hash_offset = lb_hash_mode?16:32;
    CTC_ERROR_RETURN(_sys_tsingma_hash_init(lchip));

    sal_memset(&hash_ctl, 0, sizeof(ctc_parser_hash_ctl_t));
    sal_memset(&p_hash_offset, 0, sizeof(ctc_lb_hash_offset_t));
    CTC_ERROR_RETURN(_sys_tsingma_parser_set_layer2_hash(lchip, &hash_ctl, hash_usage));
    CTC_ERROR_RETURN(_sys_tsingma_parser_set_l3_l4_hash(lchip, &hash_ctl, hash_usage));
    CTC_ERROR_RETURN(_sys_tsingma_parser_set_mpls_hash(lchip, &hash_ctl, hash_usage));
    CTC_ERROR_RETURN(_sys_tsingma_parser_set_trill_hash(lchip, &hash_ctl, hash_usage));
    CTC_ERROR_RETURN(_sys_tsingma_parser_set_fcoe_hash(lchip, &hash_ctl, hash_usage));

    CTC_SET_FLAG(hash_ctl.ip_flag, CTC_PARSER_IP_HASH_FLAGS_IPSA);
    CTC_SET_FLAG(hash_ctl.ip_flag, CTC_PARSER_IP_HASH_FLAGS_IPDA);
    CTC_ERROR_RETURN(_sys_tsingma_parser_set_l3_l4_hash(lchip, &hash_ctl, hash_usage));

    sal_memset(&hash_cfg, 0, sizeof(ctc_lb_hash_config_t));
    if (!DRV_FROM_TMM(lchip))
    {
        hash_cfg.sel_id = 1;
        hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_CONTROL;
        hash_cfg.hash_control = CTC_LB_HASH_CONTROL_HASH_TYPE_A;
        hash_cfg.value = CTC_LB_HASH_TYPE_XOR8;
        CTC_ERROR_RETURN(_sys_tsingma_hash_config_set_hash_control(lchip, &hash_cfg));
        hash_cfg.sel_id = 0;
        CTC_ERROR_RETURN(_sys_tsingma_hash_config_set_hash_control(lchip, &hash_cfg));
    }
    else
    {
        if (lb_hash_mode)
        {
            hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_CONTROL;
            for (index = 0; index < SYS_USW_LB_HASH_CTL_NUM * 2; index++)
            {
                hash_cfg.sel_id = index;
                hash_cfg.hash_control = CTC_LB_HASH_CONTROL_HASH_TYPE_A;
                hash_cfg.value = CTC_LB_HASH_TYPE_XOR8;
                CTC_ERROR_RETURN(_sys_tsingma_hash_config_set_hash_control(lchip, &hash_cfg));
            }
        }
        else
        {
            hash_cfg.cfg_type = CTC_LB_HASH_CFG_HASH_CONTROL;
            for (index = 0; index < SYS_USW_LB_HASH_CTL_NUM * 2; index++)
            {
                hash_cfg.sel_id = index / 2;
                hash_cfg.hash_control = (index % 2 == 0) ? CTC_LB_HASH_CONTROL_HASH_TYPE_A : CTC_LB_HASH_CONTROL_HASH_TYPE_B;
                hash_cfg.value = (index % 2 == 0) ? CTC_LB_HASH_TYPE_XOR8 : CTC_LB_HASH_TYPE_CRC8_POLY1;
                CTC_ERROR_RETURN(_sys_tsingma_hash_config_set_hash_control(lchip, &hash_cfg));
            }
        }
    }

    /*static linkagg*/
    p_hash_offset.hash_module = CTC_LB_HASH_MODULE_LINKAGG;
    p_hash_offset.hash_mode = CTC_LB_HASH_MODE_STATIC;
    p_hash_offset.offset = lb_hash_offset;
    CTC_ERROR_RETURN(_sys_tsingma_hash_set_lag_offset(lchip, &p_hash_offset));

    /*dlb linkagg*/
    p_hash_offset.hash_module = CTC_LB_HASH_MODULE_LINKAGG;
    p_hash_offset.hash_mode = CTC_LB_HASH_MODE_DLB_FLOW_SET;
    p_hash_offset.offset = lb_hash_offset;
    CTC_ERROR_RETURN(_sys_tsingma_hash_set_lag_offset(lchip, &p_hash_offset));

    /*selfhealing linkagg*/
    p_hash_offset.hash_module = CTC_LB_HASH_MODULE_LINKAGG;
    p_hash_offset.hash_mode = CTC_LB_HASH_MODE_LSH;
    p_hash_offset.offset = lb_hash_offset;
    CTC_ERROR_RETURN(_sys_tsingma_hash_set_lag_offset(lchip, &p_hash_offset));

    /*static stacking*/
    p_hash_offset.hash_module = CTC_LB_HASH_MODULE_STACKING;
    p_hash_offset.hash_mode = CTC_LB_HASH_MODE_STATIC;
    p_hash_offset.offset = lb_hash_offset;
    CTC_ERROR_RETURN(_sys_tsingma_hash_set_stacking_offset(lchip, &p_hash_offset, 0));

    /*dlb stacking*/
    p_hash_offset.hash_module = CTC_LB_HASH_MODULE_STACKING;
    p_hash_offset.hash_mode = CTC_LB_HASH_MODE_DLB_FLOW_SET;
    p_hash_offset.offset = lb_hash_offset;
    CTC_ERROR_RETURN(_sys_tsingma_hash_set_stacking_offset(lchip, &p_hash_offset, 0));

    /*selfhealing stacking*/
    p_hash_offset.hash_module = CTC_LB_HASH_MODULE_STACKING;
    p_hash_offset.hash_mode = CTC_LB_HASH_MODE_LSH;
    p_hash_offset.offset = lb_hash_offset;
    CTC_ERROR_RETURN(_sys_tsingma_hash_set_stacking_offset(lchip, &p_hash_offset, 0));

    /*UC for header*/
    p_hash_offset.hash_module = CTC_LB_HASH_MODULE_HEAD_LAG;
    p_hash_offset.fwd_type = CTC_LB_HASH_FWD_UC;
    p_hash_offset.profile_id = CTC_LB_HASH_GLOBAL_PROFILE;
    p_hash_offset.offset = lb_hash_offset;
    CTC_ERROR_RETURN(_sys_tsingma_hash_set_packet_head_offset(lchip, &p_hash_offset));

    /*Non-UC for header*/
    p_hash_offset.hash_module = CTC_LB_HASH_MODULE_HEAD_LAG;
    p_hash_offset.fwd_type = CTC_LB_HASH_FWD_NON_UC;
    p_hash_offset.profile_id = CTC_LB_HASH_GLOBAL_PROFILE;
    p_hash_offset.offset = lb_hash_offset;
    CTC_ERROR_RETURN(_sys_tsingma_hash_set_packet_head_offset(lchip, &p_hash_offset));

    /*ecmp*/
    p_hash_offset.hash_module = CTC_LB_HASH_MODULE_ECMP;
    p_hash_offset.hash_mode = CTC_LB_HASH_MODE_STATIC;
    p_hash_offset.profile_id = CTC_LB_HASH_GLOBAL_PROFILE;
    p_hash_offset.fwd_type = CTC_LB_HASH_FWD_IP;
    p_hash_offset.offset = 0;
    CTC_ERROR_RETURN(_sys_tsingma_hash_set_ecmp_offset(lchip, &p_hash_offset));

    p_hash_offset.hash_module = CTC_LB_HASH_MODULE_ECMP;
    p_hash_offset.hash_mode = CTC_LB_HASH_MODE_STATIC;
    p_hash_offset.profile_id = CTC_LB_HASH_GLOBAL_PROFILE;
    p_hash_offset.fwd_type = CTC_LB_HASH_FWD_NONE;
    p_hash_offset.hecmp_grp_en = 1;
    p_hash_offset.offset = 16;
    CTC_ERROR_RETURN(_sys_tsingma_hash_set_ecmp_offset(lchip, &p_hash_offset));
    return CTC_E_NONE;
}
#endif


